Skip to content

Commit fcbd88f

Browse files
justinchubyCopilot
andauthored
fix: add transformer. prefix in GPT-2 and Falcon/Bloom preprocess_weights (#113)
## Problem HF safetensors for GPT-2 and Bloom store layer weights **without** the outer `transformer.` prefix (e.g. `h.N.*`, `wte.*`, `ln_f.*`, `word_embeddings.*`). Our ONNX initialisers include it because the outer module attribute is `self.transformer`. As a result, `preprocess_weights()` produced keys that never matched any ONNX initialiser — every weight was left unloaded, and ORT rejected the model with `Node input 'transformer.wte.weight' is not a graph input, initializer, or output of a previous node.` ## Root Cause - **GPT-2 / OpenAI-GPT / GPT-SW3**: safetensors keys are `h.N.attn.*`, `wte.*`, `wpe.*`, `ln_f.*` (no prefix). GPT-Neo and GPT-BigCode already include `transformer.`. - **Bloom**: safetensors keys are `h.N.*`, `word_embeddings.*`, `ln_f.*` (no prefix). ## Fix - **`gpt2.py`**: in step 1 of the weight-normalisation loop, add `transformer.` for plain GPT-2/GPT-SW3 keys (biogpt.\*, model.\*, output_projection.\* and lm_head.\* are handled separately). - **`falcon.py`**: after the Falcon/Bloom QKV-split and rename loop, re-key entries that lack the `transformer.` or `lm_head.` prefix. ## Testing Golden tests confirmed passing after the fix: ``` tests/e2e_golden_test.py::TestL4CheckpointVerified::test_prefill_argmax_matches_golden[text-generation/gpt2] PASSED tests/e2e_golden_test.py::TestL4CheckpointVerified::test_prefill_argmax_matches_golden[text-generation/bloom-560m] PASSED ``` Also removes now-stale xfail/skip marks from `integration_test.py`: - gpt2 xfail `tie_word_embeddings graph reference issue in ORT` - bloom-560m skip `word_embeddings_layernorm not implemented` All 2277 unit tests pass. Lintrunner clean. Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 04c8e62 commit fcbd88f

3 files changed

Lines changed: 18 additions & 7 deletions

File tree

src/mobius/models/falcon.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,15 @@ def preprocess_weights(
577577
new_key = new_key.replace(".mlp.dense_4h_to_h.", ".mlp.down_proj.")
578578
new_state_dict[new_key] = value
579579

580+
# HF Falcon / Bloom safetensors omit the "transformer." prefix
581+
# (e.g. "h.N.*", "word_embeddings.*", "ln_f.*"). ONNX initialiser
582+
# names include it because the outer attribute is ``self.transformer``.
583+
# ``lm_head.*`` is a top-level attribute and stays as-is.
584+
new_state_dict = {
585+
(k if k.startswith(("transformer.", "lm_head.")) else "transformer." + k): v
586+
for k, v in new_state_dict.items()
587+
}
588+
580589
# Handle weight tying
581590
if self.config.tie_word_embeddings:
582591
embed_key = "transformer.word_embeddings.weight"

src/mobius/models/gpt2.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,15 @@ def preprocess_weights(
123123
name = "transformer.h." + name[len("biogpt.layers.") :]
124124
elif name.startswith("model.layers."):
125125
name = "transformer.h." + name[len("model.layers.") :]
126+
# GPT-2 / OpenAI-GPT / GPT-SW3 HF safetensors omit the
127+
# "transformer." prefix (e.g. "h.N.*", "wte.*", "ln_f.*").
128+
# GPT-Neo and GPT-BigCode already include it.
129+
# biogpt.* / model.* / output_projection.* / lm_head.* are
130+
# handled separately below and must not be prefixed here.
131+
elif not name.startswith(
132+
("transformer.", "biogpt.", "model.", "output_projection.", "lm_head.")
133+
):
134+
name = "transformer." + name
126135

127136
# ── 2. Top-level embedding / norm renames ────────────────────────
128137
# OpenAI-GPT

tests/integration_test.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,6 @@ def _model_accessible(model_id: str) -> bool:
9797
"openai-community/gpt2",
9898
False,
9999
id="gpt2",
100-
marks=pytest.mark.xfail(
101-
reason="tie_word_embeddings graph reference issue in ORT", strict=False
102-
),
103100
),
104101
# OPT (learned positional embeddings)
105102
pytest.param(
@@ -113,10 +110,6 @@ def _model_accessible(model_id: str) -> bool:
113110
"bigscience/bloom-560m",
114111
False,
115112
id="bloom-560m",
116-
marks=pytest.mark.skip(
117-
reason="Bloom word_embeddings_layernorm not implemented "
118-
"in FalconCausalLMModel — weights silently dropped"
119-
),
120113
),
121114
# Falcon (ALiBi attention, multi-query)
122115
pytest.param(

0 commit comments

Comments
 (0)