Skip to content

Make TransformToNewSQ handle non-relativizable trials (#5039)#5039

Closed
ItsMrLin wants to merge 3 commits intofacebook:mainfrom
ItsMrLin:export-D96574758
Closed

Make TransformToNewSQ handle non-relativizable trials (#5039)#5039
ItsMrLin wants to merge 3 commits intofacebook:mainfrom
ItsMrLin:export-D96574758

Conversation

@ItsMrLin
Copy link
Contributor

@ItsMrLin ItsMrLin commented Mar 16, 2026

Summary:

When LILO labeling trials (carrying only pairwise preference data)
coexist with Sobol/BO trials (carrying base metrics), TransformToNewSQ
and BaseRelativize must skip trials that cannot be relativized.

TorchAdapter._transform_data (D96574732) pops the pairwise preference
column before any Ax transforms run, so TransformToNewSQ only ever sees
base metrics. This means the only concern at this layer is trial-level
exclusion: LILO labeling trials have no base metrics and no status quo
data to relativize against.

Changes:

  • BaseRelativize.__init__: Collects _non_relativizable_trial_indices
    from trials with trial_type == LILO_LABELING.
  • BaseRelativize.transform_experiment_data: Excludes non-relativizable
    trials from the missing-SQ validation check and from relativization.
  • TransformToNewSQ.transform_experiment_data: Skips target trial,
    non-relativizable trials, and trials without SQ data. Drops SQ arms
    only from actually-transformed trials (non-transformed trials keep
    all arms, which PairwiseGP requires).
  • TransformToNewSQ._get_relative_data_from_obs: Returns data
    unchanged for trials without SQ data.

Reviewed By: Balandat

Differential Revision: D96574758

@meta-cla meta-cla bot added the CLA Signed Do not delete this pull request or issue due to inactivity. label Mar 16, 2026
@meta-codesync
Copy link

meta-codesync bot commented Mar 16, 2026

@ItsMrLin has exported this pull request. If you are a Meta employee, you can view the originating Diff in D96574758.

@meta-codesync meta-codesync bot changed the title Make TransformToNewSQ handle heterogeneous trial data Make TransformToNewSQ handle heterogeneous trial data (#5039) Mar 17, 2026
ItsMrLin added a commit to ItsMrLin/Ax that referenced this pull request Mar 17, 2026
Summary:

When LILO labeling trials (carrying only pairwise preference data)
coexist with Sobol/BO trials (carrying base metrics), TransformToNewSQ
and BaseRelativize must handle two distinct concerns:

1. **LILO trials must not be transformed (trial-level).**
   LILO labeling trials carry only pairwise preference labels — they
   have no base metrics, so there is no status quo data to relativize
   against.  These trials are excluded from transformation entirely
   via `_lilo_trial_indices` (built at init from `trial_type ==
   LILO_LABELING`).  Their SQ arms are also preserved (not dropped)
   because PairwiseGP requires both arms in each pairwise comparison.

2. **The preference metric may be missing from non-LILO trials
   (metric-level).**
   After `configure_lilo()`, the optimization config includes
   `pairwise_preference_query`.  But Sobol/BO trials were created
   before LILO was configured — they have data for base metrics like
   `branin` but not for the preference metric.  This is expected.
   Without special handling, the transform would error or skip the
   entire trial, blocking relativization of base metrics that *do*
   have valid data.  Per-metric masking solves this: for each metric,
   only trials whose SQ data includes that metric are relativized;
   others are left untouched via NaN placeholders.

In short:

|  Concern               | What                           | How |
| ----------------------|--------------------------------|----------------------------|
|  LILO trials           | Skip entire rows by trial idx  | `_lilo_trial_indices` mask|
|  Preference metric     | Skip per-metric when SQ absent | NaN placeholders + mask|

The first is a hard exclusion (these trials should never be touched).
The second is a graceful degradation (this metric is absent from some
trials, but other metrics in those same trials should still be
relativized normally).

Differential Revision: D96574758
ItsMrLin added a commit to ItsMrLin/Ax that referenced this pull request Mar 17, 2026
Summary:
Pull Request resolved: facebook#5039

When LILO labeling trials (carrying only pairwise preference data)
coexist with Sobol/BO trials (carrying base metrics), TransformToNewSQ
and BaseRelativize must handle two distinct concerns:

1. **LILO trials must not be transformed (trial-level).**
   LILO labeling trials carry only pairwise preference labels — they
   have no base metrics, so there is no status quo data to relativize
   against.  These trials are excluded from transformation entirely
   via `_lilo_trial_indices` (built at init from `trial_type ==
   LILO_LABELING`).  Their SQ arms are also preserved (not dropped)
   because PairwiseGP requires both arms in each pairwise comparison.

2. **The preference metric may be missing from non-LILO trials
   (metric-level).**
   After `configure_lilo()`, the optimization config includes
   `pairwise_preference_query`.  But Sobol/BO trials were created
   before LILO was configured — they have data for base metrics like
   `branin` but not for the preference metric.  This is expected.
   Without special handling, the transform would error or skip the
   entire trial, blocking relativization of base metrics that *do*
   have valid data.  Per-metric masking solves this: for each metric,
   only trials whose SQ data includes that metric are relativized;
   others are left untouched via NaN placeholders.

In short:

|  Concern               | What                           | How |
| ----------------------|--------------------------------|----------------------------|
|  LILO trials           | Skip entire rows by trial idx  | `_lilo_trial_indices` mask|
|  Preference metric     | Skip per-metric when SQ absent | NaN placeholders + mask|

The first is a hard exclusion (these trials should never be touched).
The second is a graceful degradation (this metric is absent from some
trials, but other metrics in those same trials should still be
relativized normally).

Differential Revision: D96574758
ItsMrLin added a commit to ItsMrLin/Ax that referenced this pull request Mar 18, 2026
Summary:

When LILO labeling trials (carrying only pairwise preference data)
coexist with Sobol/BO trials (carrying base metrics), TransformToNewSQ
and BaseRelativize must handle two distinct concerns:

1. **LILO trials must not be transformed (trial-level).**
   LILO labeling trials carry only pairwise preference labels — they
   have no base metrics, so there is no status quo data to relativize
   against.  These trials are excluded from transformation entirely
   via `_lilo_trial_indices` (built at init from `trial_type ==
   LILO_LABELING`).  Their SQ arms are also preserved (not dropped)
   because PairwiseGP requires both arms in each pairwise comparison.

2. **The preference metric may be missing from non-LILO trials
   (metric-level).**
   After `configure_lilo()`, the optimization config includes
   `pairwise_preference_query`.  But Sobol/BO trials were created
   before LILO was configured — they have data for base metrics like
   `branin` but not for the preference metric.  This is expected.
   Without special handling, the transform would error or skip the
   entire trial, blocking relativization of base metrics that *do*
   have valid data.  Per-metric masking solves this: for each metric,
   only trials whose SQ data includes that metric are relativized;
   others are left untouched via NaN placeholders.

In short:

|  Concern               | What                           | How |
| ----------------------|--------------------------------|----------------------------|
|  LILO trials           | Skip entire rows by trial idx  | `_lilo_trial_indices` mask|
|  Preference metric     | Skip per-metric when SQ absent | NaN placeholders + mask|

The first is a hard exclusion (these trials should never be touched).
The second is a graceful degradation (this metric is absent from some
trials, but other metrics in those same trials should still be
relativized normally).

Reviewed By: Balandat

Differential Revision: D96574758
ItsMrLin added a commit to ItsMrLin/Ax that referenced this pull request Mar 18, 2026
Summary:
Pull Request resolved: facebook#5039

When LILO labeling trials (carrying only pairwise preference data)
coexist with Sobol/BO trials (carrying base metrics), TransformToNewSQ
and BaseRelativize must handle two distinct concerns:

1. **LILO trials must not be transformed (trial-level).**
   LILO labeling trials carry only pairwise preference labels — they
   have no base metrics, so there is no status quo data to relativize
   against.  These trials are excluded from transformation entirely
   via `_lilo_trial_indices` (built at init from `trial_type ==
   LILO_LABELING`).  Their SQ arms are also preserved (not dropped)
   because PairwiseGP requires both arms in each pairwise comparison.

2. **The preference metric may be missing from non-LILO trials
   (metric-level).**
   After `configure_lilo()`, the optimization config includes
   `pairwise_preference_query`.  But Sobol/BO trials were created
   before LILO was configured — they have data for base metrics like
   `branin` but not for the preference metric.  This is expected.
   Without special handling, the transform would error or skip the
   entire trial, blocking relativization of base metrics that *do*
   have valid data.  Per-metric masking solves this: for each metric,
   only trials whose SQ data includes that metric are relativized;
   others are left untouched via NaN placeholders.

In short:

|  Concern               | What                           | How |
| ----------------------|--------------------------------|----------------------------|
|  LILO trials           | Skip entire rows by trial idx  | `_lilo_trial_indices` mask|
|  Preference metric     | Skip per-metric when SQ absent | NaN placeholders + mask|

The first is a hard exclusion (these trials should never be touched).
The second is a graceful degradation (this metric is absent from some
trials, but other metrics in those same trials should still be
relativized normally).

Reviewed By: Balandat

Differential Revision: D96574758
@meta-codesync meta-codesync bot changed the title Make TransformToNewSQ handle heterogeneous trial data (#5039) Make TransformToNewSQ handle non-relativizable trials (#5039) Mar 18, 2026
ItsMrLin added a commit to ItsMrLin/Ax that referenced this pull request Mar 18, 2026
Summary:

When LILO labeling trials (carrying only pairwise preference data)
coexist with Sobol/BO trials (carrying base metrics), TransformToNewSQ
and BaseRelativize must skip trials that cannot be relativized.

`TorchAdapter._transform_data` (D96574732) pops the pairwise preference
column before any Ax transforms run, so TransformToNewSQ only ever sees
base metrics.  This means the only concern at this layer is trial-level
exclusion: LILO labeling trials have no base metrics and no status quo
data to relativize against.

Changes:

- **`BaseRelativize.__init__`**: Collects `_non_relativizable_trial_indices`
  from trials with `trial_type == LILO_LABELING`.
- **`BaseRelativize.transform_experiment_data`**: Excludes non-relativizable
  trials from the missing-SQ validation check and from relativization.
- **`TransformToNewSQ.transform_experiment_data`**: Skips target trial,
  non-relativizable trials, and trials without SQ data.  Drops SQ arms
  only from actually-transformed trials (non-transformed trials keep
  all arms, which PairwiseGP requires).
- **`TransformToNewSQ._get_relative_data_from_obs`**: Returns data
  unchanged for trials without SQ data.

Reviewed By: Balandat

Differential Revision: D96574758
@codecov-commenter
Copy link

codecov-commenter commented Mar 18, 2026

Codecov Report

❌ Patch coverage is 94.63087% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.73%. Comparing base (2d4750a) to head (531d8af).

Files with missing lines Patch % Lines
ax/adapter/transforms/relativize.py 87.50% 2 Missing ⚠️
ax/adapter/transforms/transform_to_new_sq.py 88.88% 2 Missing ⚠️
ax/storage/sqa_store/decoder.py 60.00% 2 Missing ⚠️
...apter/transforms/tests/test_transform_to_new_sq.py 98.36% 1 Missing ⚠️
ax/storage/sqa_store/encoder.py 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5039      +/-   ##
==========================================
- Coverage   96.73%   96.73%   -0.01%     
==========================================
  Files         606      606              
  Lines       66242    66370     +128     
==========================================
+ Hits        64080    64203     +123     
- Misses       2162     2167       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Summary:
Move `LLMMessage` dict conversion from the `experiment.llm_messages`
getter/setter to the storage encoders/decoders, following Ax convention
that domain objects hold domain types and serialization happens at the
storage boundary.

**`experiment.py`**: The setter now stores `LLMMessage` objects directly
in `_properties`. The getter handles both `LLMMessage` objects (new path)
and plain dicts (backward compat with previously stored data).

**JSON store**: No explicit changes needed — the encoder's generic
dataclass fallback auto-serializes `LLMMessage` with a `__type` tag,
and `LLMMessage` is already registered in `CORE_DECODER_REGISTRY`.

**SQA store**: The encoder converts `LLMMessage` → dict via
`dataclasses.asdict()` in the properties copy before DB write (same
pattern as `pruning_target_parameterization`). The decoder converts
dicts → `LLMMessage` after loading properties, in both
`_init_experiment_from_sqa` and `_init_mt_experiment_from_sqa`.

Differential Revision: D96434290
Summary:
In LILO (LLM-In-the-Loop Optimization) experiments, the optimization
config objective is `pairwise_pref_query` — a derived metric that only
LILO labeling trials carry data for.  `get_target_trial_index()` then
selects these labeling trials (which have COMPLETE pairwise data) as
the relativization reference instead of non-LILO trials (which have base
metric data).  The target trial's SQ then lacks base metrics, causing
TransformToNewSQ and downstream model fitting to fail.

Fix:
1. Exclude LILO labeling trials (`trial_type == LILO_LABELING`) from
   the target trial candidate set.
2. For LILO experiments, accept INCOMPLETE metric availability so that
   non-LILO trials (which have base-metric data but lack the pairwise
   preference metric) can serve as relativization references.

Differential Revision: D96574746
ItsMrLin added a commit to ItsMrLin/Ax that referenced this pull request Mar 18, 2026
Summary:

When LILO labeling trials (carrying only pairwise preference data)
coexist with Sobol/BO trials (carrying base metrics), TransformToNewSQ
and BaseRelativize must skip trials that cannot be relativized.

`TorchAdapter._transform_data` (D96574732) pops the pairwise preference
column before any Ax transforms run, so TransformToNewSQ only ever sees
base metrics.  This means the only concern at this layer is trial-level
exclusion: LILO labeling trials have no base metrics and no status quo
data to relativize against.

Changes:

- **`BaseRelativize.__init__`**: Collects `_non_relativizable_trial_indices`
  from trials with `trial_type == LILO_LABELING`.
- **`BaseRelativize.transform_experiment_data`**: Excludes non-relativizable
  trials from the missing-SQ validation check and from relativization.
- **`TransformToNewSQ.transform_experiment_data`**: Skips target trial,
  non-relativizable trials, and trials without SQ data.  Drops SQ arms
  only from actually-transformed trials (non-transformed trials keep
  all arms, which PairwiseGP requires).
- **`TransformToNewSQ._get_relative_data_from_obs`**: Returns data
  unchanged for trials without SQ data.

Reviewed By: Balandat

Differential Revision: D96574758
ItsMrLin added a commit to ItsMrLin/Ax that referenced this pull request Mar 18, 2026
Summary:

When LILO labeling trials (carrying only pairwise preference data)
coexist with Sobol/BO trials (carrying base metrics), TransformToNewSQ
and BaseRelativize must skip trials that cannot be relativized.

`TorchAdapter._transform_data` (D96574732) pops the pairwise preference
column before any Ax transforms run, so TransformToNewSQ only ever sees
base metrics.  This means the only concern at this layer is trial-level
exclusion: LILO labeling trials have no base metrics and no status quo
data to relativize against.

Changes:

- **`BaseRelativize.__init__`**: Collects `_non_relativizable_trial_indices`
  from trials with `trial_type == LILO_LABELING`.
- **`BaseRelativize.transform_experiment_data`**: Excludes non-relativizable
  trials from the missing-SQ validation check and from relativization.
- **`TransformToNewSQ.transform_experiment_data`**: Skips target trial,
  non-relativizable trials, and trials without SQ data.  Drops SQ arms
  only from actually-transformed trials (non-transformed trials keep
  all arms, which PairwiseGP requires).
- **`TransformToNewSQ._get_relative_data_from_obs`**: Returns data
  unchanged for trials without SQ data.

Reviewed By: Balandat

Differential Revision: D96574758
Summary:
Pull Request resolved: facebook#5039

When LILO labeling trials (carrying only pairwise preference data)
coexist with Sobol/BO trials (carrying base metrics), TransformToNewSQ
and BaseRelativize must skip trials that cannot be relativized.

`TorchAdapter._transform_data` (D96574732) pops the pairwise preference
column before any Ax transforms run, so TransformToNewSQ only ever sees
base metrics.  This means the only concern at this layer is trial-level
exclusion: LILO labeling trials have no base metrics and no status quo
data to relativize against.

Changes:

- **`BaseRelativize.__init__`**: Collects `_non_relativizable_trial_indices`
  from trials with `trial_type == LILO_LABELING`.
- **`BaseRelativize.transform_experiment_data`**: Excludes non-relativizable
  trials from the missing-SQ validation check and from relativization.
- **`TransformToNewSQ.transform_experiment_data`**: Skips target trial,
  non-relativizable trials, and trials without SQ data.  Drops SQ arms
  only from actually-transformed trials (non-transformed trials keep
  all arms, which PairwiseGP requires).
- **`TransformToNewSQ._get_relative_data_from_obs`**: Returns data
  unchanged for trials without SQ data.

Reviewed By: Balandat

Differential Revision: D96574758
@meta-codesync
Copy link

meta-codesync bot commented Mar 18, 2026

This pull request has been merged in 84838db.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed Do not delete this pull request or issue due to inactivity. fb-exported Merged meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants