recipe(multilingual-e5-small): add CPU fp32/fp16 feature-extraction and sentence-similarity recipes - #1182
Conversation
|
APPROVE coverage: partial Checklist evidence:
Residual note: the |
…nd sentence-similarity recipes intfloat/multilingual-e5-small is a BertModel sentence embedder. The default build fails at quantize (calibration reader omits token_type_ids); these quant:null float recipes skip that step and build a working float model. L2 PyTorch-vs-ONNX embedding cosine 1.000000, retrieval ranking preserved. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
5953053 to
8e7c621
Compare
REQUEST_CHANGESFinding
Independent review evidence
No implementation, recipe, L0, L2, L3, Analyze, thread, status-check, body, or Lane A blocker was found beyond the explicit fp16 L1 printed-line requirement above. The orchestrator should route this fix to tester and explainer, then return the refreshed exact head and sealed handoffs for re-review. |
APPROVEIndependent re-review of Reviewed identity and scope
Prior blocker: resolvedThe previous blocker was an evidence-contract/CLI-output drift issue, not an fp16 artifact failure. Under the current reviewer contract and Lane A I independently parsed the two raw repaired
Both records identify the exact candidate-owned artifacts, use 100 iterations plus 10 warmups, and exited 0. Captured stdout is text-identical to each JSON report; stderr contains zero The other two parts of the fail-closed precision proof also hold for both artifacts:
The original blocker is therefore fully resolved by authoritative schema-v2 precision plus unchanged structural proof. Independent validation retained on unchanged codeI revalidated the sealed prior reviewer evidence against the unchanged head/base: all 97 entries match their recorded hashes. I also revalidated all 160 original tester evidence entries and all 44 repair entries; no missing or mismatched file was found. Reuse is valid because candidate, base/current main, recipes, built artifacts, and relevant dependencies are unchanged. I did not rerun Eval. Prior independent reruns remain:
Goal evidence remains complete and unchanged except for the two refreshed fp16 L1 rows:
Complete Analyze evidence is retained for all four artifacts. Component mapping covers embeddings plus 12 encoder attention/feed-forward blocks, with 372/373 mapped nodes and zero partial or unmapped nodes; runtime pooling/normalization is explicitly excluded from the ONNX mapping. Op analysis reports 372/373 operators across 15 types, with dominant Reshape 121, Gemm 72, Transpose 48, Add 38, and LayerNormalization 25. Across the six rule-backed targets, no unsupported type is reported; Body and methodology fidelityThe live body is byte-equal to the repaired canonical body after CRLF/LF normalization, hash The methodology declaration now accurately cites ModelKitArtifacts Lane A PR #216, exact head GitHub gates
No blockers remain. This approval is a normal conversation-comment verdict only; the PR correctly remains DRAFT, and this comment does not authorize readiness or any other PR mutation. |
Summary
Adds complete CPU fp32/fp16 support for
intfloat/multilingual-e5-smallacross feature extraction and sentence similarity. The Effort L2 contribution ships four task/precision recipes plus a metadata-driven shared input fix and regression coverage; Outcome L2 reached the committed Goal L3 with full coverage on candidate8e7c621a2312a3ef45b08c43e7347301e992f842. The bounded L3 result is functional-smoke evidence only, not representative benchmark accuracy.Model metadata
What the model does
intfloat/multilingual-e5-smallis a multilingual text-embedding checkpoint. It encodes prefixed text with a 12-layerBertModelinto token-level hidden states; the published SentenceTransformers pipeline applies attention-mask-aware mean pooling and L2 normalization to obtain 384-dimensional embeddings for retrieval, semantic similarity, clustering, and related feature use.modules.json,1_Pooling/config.json, and model config; current-mainwinml inspectfor feature extraction and sentence similarity.verified.Primary user stories
query:/passage:asymmetric retrieval prefixes. Confidence:verified.query:prefix on symmetric semantic-similarity tasks. Confidence:verified.query:prefix on embedding-as-feature use. Confidence:verified.Supported tasks
feature-extraction, and current-mainwinml inspectresolvesAutoModelandBertIOConfig. Confidence:verified.pipeline_tag=sentence-similarity,library_name=sentence-transformers) and supported by WinML while using the feature-extraction export contract. Confidence:verified.Model architecture
architectures=[BertModel]), Transformers 5.14.1BertModelsource, and pinned SentenceTransformers module/pooling configs (verified).Validation and support evidence
Baseline
Baseline was fully rerun at current
maine564a6375d6cd2b596fb3d21d918f07824b349e0with WinML0.2.0.AutoModel/BertIOConfig; sentence similarity deliberately uses the feature-extraction ONNX graph contract.winml configproduced task-specific anchors and has no precision selector. The repaired final recipes are structurally identical to the corresponding frozen current-main fp32/fp16 auto-config anchors. This is not a new task-family registry.VENDOR-ONLY. Optimum's BERT registry already suppliesfeature-extraction; WinML adds no vendor task, and sentence similarity reuses the feature-extraction export contract.67.6s(31.0sexport,31.1soptimize),quant=null, 448.4 MB float model. ONNX checker passed: IR 8, opset 17, 372 nodes, three int32[1,512]inputs, and float32[1,512,384]last_hidden_state. The historical default-quant failure is not current.96.87 ms, p5094.99 ms, p90108.50 ms, p95111.20 ms, p99115.63 ms,10.32 samples/s, total RSS delta+81.4 MB.last_hidden_statemax absolute error1.996755599975586e-06(1.997e-6), mean absolute error2.1955554529995425e-07, cosine0.9999999403953552; pooled normalized embedding cosine minimum0.9999999403953552. PyTorch and ONNX retrieval rankings were identical for the pinned bilingual examples.token_type_idswhile the ONNX graph required it.Goal
The final Goal ladder passed at every tier: L0
4/4, L14/4, L24/4, and L3PASS. The ceiling was not downgraded.Outcome
Outcome L2 shipped at final candidate
8e7c621a2312a3ef45b08c43e7347301e992f842; highest Goal verdict is L3 PASS, coverage is full, and there are no deferred tuples or blockers.Shipped paths:
examples/recipes/intfloat_multilingual-e5-small/cpu/cpu/feature-extraction_fp32_config.jsonexamples/recipes/intfloat_multilingual-e5-small/cpu/cpu/feature-extraction_fp16_config.jsonexamples/recipes/intfloat_multilingual-e5-small/cpu/cpu/sentence-similarity_fp32_config.jsonexamples/recipes/intfloat_multilingual-e5-small/cpu/cpu/sentence-similarity_fp16_config.jsonsrc/winml/modelkit/models/winml/feature_extraction.pytests/unit/models/auto/test_feature_extraction.pyModel findings
bert-011throughbert-016were appended on the separate Lane A Draft ModelKitArtifacts PR #216, final head8c67d9cb69ac1ca464beabe82bac1771c4edd912, labeledmodel-scale-by-skill. Methodology declaration:no_friction:false; reviewer-discovered doc-code drift captured as _meta-108 with paired tester/reviewer contract edits in pushed Lane A PR #216._meta-108records only that schema-v2 perf precision supersedes the stale literal console gate.Per-EP/device/precision results and Functional smoke Eval
Goal ladder and CPU perf
Both fp16 builds used
--precision fp16without--no-quant. Currentwinml perf --format jsonemitted schema-v2 authoritative resolvedmodel_info.precision="fp16"and corroborating requested-policybenchmark_info.precision="fp16"for both fp16 artifacts. Each contains 200FLOAT16initializers and234,931,456external-data bytes, versus 200FLOATinitializers and470,027,776bytes for fp32, a ratio of0.4998246231; float I/O is preserved.L2 numeric and retrieval parity
Pinned PyTorch checkpoint revision:
614241f622f53c4eeff9890bdc4f31cfecc418b3.Functional smoke Eval
Functional smoke only; this is not representative benchmark accuracy or model-quality evidence. One final-SHA FP32 CPU sentence-similarity run passed on candidate
8e7c621a2312a3ef45b08c43e7347301e992f842.614241f622f53c4eeff9890bdc4f31cfecc418b3; splittrain; deterministic no-shuffle selection with seed0.sentence1,sentence2,score,source_query_row,source_passage_row, andrelationwere verified. Labels were1.0for same-source matches and0.0for cross-source negatives; predictions were attention-mask-aware mean-pooled embedding cosine similarities. Schema, label semantics, and prediction semantics all passed.token_type_ids; all 8 wrapper feeds synthesized all-zero int32[1,512]values. The former missing-input blocker was therefore removed through the shared metadata-driven input capability.cosine_spearman=89.4427on the MTEB[-100, 100]scale.Delta
All four recipe paths listed under Outcome were repaired and are structurally identical to their current-main auto-config anchors. Relative to the pre-repair recipes, all four changed
/export/compatibility/transformers_attentionfrom absent to"eager". The fp32 recipes retain/quant = null. Both fp16 recipes changed/quantfromnullto the full current auto-config block, including/quant/mode = "fp16",/quant/model_id = "intfloat/multilingual-e5-small",/quant/model_type = "bert",/quant/fp16_keep_io_types = true, and task-specific/quant/taskvalues of"feature-extraction"or"sentence-similarity". These deltas are reducibility-consistent: eager attention is already class-wide current-source behavior, while precision and task are tuple intent rather than checkpoint hardcoding.examples/recipes/README.mdis unchanged.Shared source and regression paths are
src/winml/modelkit/models/winml/feature_extraction.pyandtests/unit/models/auto/test_feature_extraction.py. No-recipe acceptance passed for final-SHA FP32 feature extraction and sentence similarity; the change does not add or modify a task-family registry.Bug fix explanation
Missing required inputs: {'token_type_ids'}when the tokenizer emittedinput_idsandattention_maskbut the exported ONNX graph also declaredtoken_type_ids.WinMLModelForFeatureExtraction.forwardnow synthesizes an all-zerotoken_type_idstensor only when ONNX input metadata declares that input, the tokenizer omitted it,input_idssupplies the realized batch/sequence shape, declared dtype/shape metadata exists, and every static required dimension matches. The tensor uses the realizedinput_idsshape and exact declared ONNX dtype before normal strict validation.input_ids; it contains no model ID ormodel_typebranch and applies to the single-text feature-extraction abstraction.token_type_idsreceives the safe zero default; unrelated missing inputs and incompatible static shapes still fail; synthesized dtype/shape follows graph metadata; output names/shapes, attention-mask pooling, sentence-similarity postprocessing, and recipe-owned semantics are unchanged. The intentional change is that single-segment paths can now feed graphs requiring omitted segment IDs.13 passed in 16.92s; models/loader/datasets/export1527 passed, 6 skipped, 2 xfailed; optim711 passed, 16 skipped, 1 xfailed; commands/config/build/compiler/session/eval3563 passed, 9 skipped, 1 warning; remaining core/ONNX/cache/utils/helpers/sysinfo/inspect/optracing/regression/CLI869 passed, 2 skipped, 1 deselected, 1 warning; analyze1526 passed, 45 skipped. Total non-overlapping completed tests:8196. Ruff reportedAll checks passed!; mypy reported no issues in 435 source files.Analyze summary — component level and op level
Static rule analysis PASS completed for all four artifacts. These classifications are static compatibility evidence, not runtime execution or a claim that accelerator inference was run.
Component-level summary
GatherpartialGatherpartialGatherpartialGatherpartialThere are no mapping gaps.
Op-level summary
Whereunknown; QNN GPU/NPU: same plusGatherpartialWhereunknown; QNN GPU/NPU: same plusGatherpartialWhereunknown; QNN GPU/NPU: same plusGatherpartialWhereunknown; QNN GPU/NPU: same plusGatherpartialThe six rule-backed targets are
NvTensorRTRTXExecutionProvider/GPU,OpenVINOExecutionProvider/{CPU,GPU,NPU}, andQNNExecutionProvider/{GPU,NPU}. No rule-backed target reports an unsupported type. Rule-less CPU, CUDA, MIGraphX, and DML groups classify all 15 operator types as unknown.Reproduce commands