Fix FP16 weight detection in NeuralNetworkBuilder.make_updatable (only first layer was checked) - #2858
Open
Anai-Guo wants to merge 1 commit into
Open
Fix FP16 weight detection in NeuralNetworkBuilder.make_updatable (only first layer was checked)#2858Anai-Guo wants to merge 1 commit into
Anai-Guo wants to merge 1 commit into
Conversation
`_check_fp16_weight_param_exists` had its `return False` indented inside the `for layer in layers` loop, so only the first layer was ever inspected. A model whose first layer is FP32 but a later layer holds FP16 weights was wrongly allowed to be marked updatable. The same function also returned early for any `uniDirectionalLSTM` layer (even when it had no FP16 params), and for `branch`/`loop` layers it read `.float16Value` off nested `NeuralNetwork` messages, which raises AttributeError. Recurse into the nested networks instead. `test_nn_partial_fp16_make_updatable_fail` was defined twice in MLModelUpdatableTest, so the first definition -- which covers exactly this case -- never ran (and fails against the old check). Rename the second definition to `test_nn_updatable_fp16_quantize_fail`, which matches what it tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
NeuralNetworkBuilder.make_updatable()is supposed to refuse models that contain FP16 weight params, but_check_fp16_weight_param_exists()only ever looked at the first layer: itsreturn Falsewas indented inside thefor layer in layers:loop.So a model like
[ip1 (FP32), ip2 (FP16)]was silently marked updatable.This PR also fixes two more bugs in the same function:
uniDirectionalLSTM: it didreturn self._check_fp16_weight_params_lstms(...), so the scan stopped at the first LSTM layer even when that LSTM was FP32.branch/loop: it read.float16ValuefromifBranch/elseBranch/conditionNetwork/bodyNetwork. Those are nestedNeuralNetworkmessages with no such field, so this raisedAttributeError. It now recurses into their.layers.Why the test suite didn't catch it
MLModelUpdatableTest.test_nn_partial_fp16_make_updatable_failwas defined twice. The second definition replaced the first, so the first one never ran. That first one covers exactly this case: quantize every layer exceptip1to FP16, then expectmake_updatableto raise.The second definition tests something else (quantizing an already-updatable model), so I renamed it to
test_nn_updatable_fp16_quantize_fail. Both tests run now.Verification
Linux,
coremltools==9.0wheel (itsbuilder.pyis byte-identical tomain), withtest_model_updatable.pyfrom this branch:pytest test_model_updatable.pybuilder.py)test_nn_partial_fp16_make_updatable_fail,AssertionError: ValueError not raisedI also called
_check_fp16_weight_param_existsdirectly on hand-built layer lists:[fp32 ip, fp16 ip]False❌True[fp32 LSTM, fp16 ip]False❌True[branch containing fp16 ip]AttributeError❌True[loop containing fp32 ip]AttributeError❌False[fp32 ip, loop containing fp32 ip]FalseFalse🤖 Generated with Claude Code