-
Goal: match PyTorch branch behavior to TensorFlow master for class I presentation prediction.
-
Confirmed mismatch is isolated to
processing_predictor_with_flankspath:- Affinity outputs match TF nearly exactly.
- Processing without flanks matches TF nearly exactly.
- Processing with flanks differs materially.
-
Intermediate feature comparison (single processing model) shows:
n_flank_cleaved,n_flank_internal_cleaved,c_flank_cleaved,c_flank_internal_cleavedmatch TF.- Only
n_flank_avg_denseandc_flank_avg_denseinputs differ.
-
Root cause identified:
- TF computes masked flank averages with
reduce_mean(..., axis=1)over full sequence length. - Current PyTorch computes average over flank positions only.
- This changes the two flank-average scalar features and can change top peptide ranking in presentation mode.
- TF computes masked flank averages with
-
Fix implemented:
- Updated
Class1ProcessingModelN/C flank-average pooling math to mirror TF exactly:mean((x + 1) * mask, axis=sequence_axis) - 1- denominator is full sequence length.
- Updated
-
Validation after fix:
- Single-model intermediate features now match TF to float noise.
- With-flanks processing predictions now match TF to float noise.
- End-to-end presentation predictions for test sequences now match TF best-peptide selection.
test/test_class1_presentation_predictor.py::test_downloaded_predictorpasses.- Parity test subset passes:
test/test_master_compat_predictions.pytest/test_released_master_predictions.pytest/test_pytorch_regressions.py
-
Regression coverage:
- Added
test_processing_flank_averages_use_tf_masked_mean_semanticsintest/test_pytorch_regressions.py.
- Added
-
Tooling add-on:
- Added
scripts/modal_train_mhcflurry.pyfor running parallel training jobs on Modal.
- Added
-
Random TF-vs-PyTorch comparison harness improvements:
- Added curated default allele panel in
scripts/compare_tf_pytorch_random_outputs.py:- ~30 common HLA alleles plus a few animal alleles (
--allele-panel iedb_plus_animals).
- ~30 common HLA alleles plus a few animal alleles (
- Reduced duplicate work in backend prediction:
- Reused
Class1PresentationPredictor.predict(...)processing outputs forprocessing_with_scoreandprocessing_without_scorecolumns. - Removed separate direct processing predictor passes.
- Reused
- Runtime sanity:
- Full
run --num-examples 5000dropped from ~142s to ~80s on this machine.
- Full
- Added curated default allele panel in
-
Added cross-product parity analysis workflow:
- New script:
scripts/cross_allele_parity_analysis.py - Generates random peptides uniformly across supported lengths (requested 7-15).
- Crosses peptides against curated allele panel and predicts PT vs TF.
- Produces:
- prediction tables
- numeric parity summaries
- break analysis tables/report
- plots under
plots/
- New script:
-
Executed full run:
1000peptides x35alleles =35000pMHC rows- lengths:
7..15 - key result: no thresholded break events observed; differences remained at expected floating-point noise scale for score outputs and tiny absolute nM differences for affinity outputs.
-
Follow-up experiment with random flanks:
- Updated
scripts/cross_allele_parity_analysis.pyto:- generate random N/C flanks per peptide (length 5/5 from model support),
- enforce pre-run uniqueness checks on peptide entries:
- no repeated
peptide,n_flank, orc_flank, - no duplicate
(peptide, n_flank, c_flank)rows, - no duplicate
(peptide, allele, n_flank, c_flank)in full dataset,
- no repeated
- enforce post-run presentation sanity checks on both PT and TF:
- at least 1% rows with score > 0.2,
- at least one row with score > 0.9.
- Run output dir:
/tmp/mhcflurry-cross-allele-1000-randflanks1000peptides x35alleles =35000rows.
- Sanity thresholds passed:
- PT with-flanks: 1.28% > 0.2, max 0.973
- TF with-flanks: 1.28% > 0.2, max 0.973
- PT without-flanks: 1.32% > 0.2, max 0.970
- TF without-flanks: 1.32% > 0.2, max 0.970
- Updated
-
High-score fixture extraction for unit tests:
- Added
scripts/extract_high_presentation_fixture.py. - Extracted TF fixture rows from
/tmp/mhcflurry-cross-allele-1000-randflanks/tf_predictions.csv.gz:- selected peptide+flank contexts where any allele had presentation score > 0.9,
- retained all alleles for each selected context (including low scorers),
- produced
315rows (9contexts x35alleles).
- Added fixture files:
test/data/master_released_class1_presentation_highscore_rows.csv.gztest/data/master_released_class1_presentation_highscore_rows_metadata.json
- Added regression test:
test/test_released_presentation_highscore_rows.py- validates fixture high/low context properties and compares released PyTorch predictions against TF fixture outputs.
- Added
-
Packaging / Torch readiness checks:
- Verified
setup.pypublishestorch>=2.0.0in metadata and wheel:python setup.py egg_infopython -m pip wheel --no-deps .
- Verified generated metadata includes
Requires-Dist: torch>=2.0.0. - Editable install attempt failed in this sandbox due permissions in
shared virtualenv
bin/path, not due packaging metadata.
- Verified
-
Warning triage:
- Important forward-compat warnings fixed:
class1_presentation_predictor.py: avoididxminon all-NA rows.random_negative_peptides.py: avoid assigningNaNinto int-typed frame.
- Test warning cleanup:
test_class1_processing_neural_network.py: avoidSettingWithCopyWarningby copying train/test subsets before assignment.
- Deprecated imports cleanup:
downloads.py: replacedpipes.quotewithshlex.quote.downloads.py: replacedpkg_resources.resource_stringwithimportlib.resources.files(...).read_text().
- Important forward-compat warnings fixed:
-
Targeted validation after fixes:
pytest -q test/test_class1_presentation_predictor.py::test_downloaded_predictor_invalid_peptidespytest -q test/test_random_negative_peptides.py::test_random_negative_peptides_by_allelepytest -q test/test_class1_processing_neural_network.py::test_small- Result: all pass; only isolated
pytest.mark.slowregistration warning remains when running that single test file directly.