Skip to content

[model] support Nanbeige4.2 Looped Transformer for LoRA/full SFT - #10668

Open
4teven wants to merge 3 commits into
hiyouga:mainfrom
4teven:feat/support-nanbeige42-loop-transformer
Open

[model] support Nanbeige4.2 Looped Transformer for LoRA/full SFT#10668
4teven wants to merge 3 commits into
hiyouga:mainfrom
4teven:feat/support-nanbeige42-loop-transformer

Conversation

@4teven

@4teven 4teven commented Jul 22, 2026

Copy link
Copy Markdown

Summary

  • Add Nanbeige4.2 Looped Transformer support (model_type=nanbeige, trust_remote_code) for LoRA and full SFT.
  • Register nanbeige / nanbeige_nothink chat templates and WebUI model entries for Base/Instruct.
  • Patch transformers>=5 rope_scaling injection so remote modeling_nanbeige.py can initialize RoPE correctly.
  • Add LoRA, QLoRA, and full SFT example configs.

Notes

  • Nanbeige4.2 reuses 22 layers with num_loops=2 (roughly 2x forward compute vs a plain 22-layer model).
  • Full SFT example uses DeepSpeed ZeRO-3; multi-GPU is recommended.
  • QLoRA example is preferred on smaller GPUs.

Test plan

  • Load config/tokenizer with trust_remote_code=true, use_fast_tokenizer=false
  • LlamaFactory LoRA (4-bit) load + short forward/backward (finite loss, LoRA grads present)
  • Template encode checks for nanbeige / nanbeige_nothink
  • Multi-GPU full SFT with examples/train_full/nanbeige42_full_sft.yaml — validated on the production GPU cluster after fixing the transformers>=5.x remote-code incompatibilities (see commit db026093 and the follow-up comment: _tied_weights_keys list->dict crash during checkpoint save, and rope_scaling["type"] KeyError in standalone from_pretrained).

Add Nanbeige4.2 model registration, chat templates, transformers>=5 rope_scaling compatibility patch, and training examples.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

刘泓睿 and others added 2 commits July 22, 2026 14:53
Add Base pretrain/SFT examples with ChatML special-token setup, and clarify that Base and Instruct share the architecture but use different tokenizer paths.
Nanbeige4.2's trust_remote_code files predate the transformers>=5.x
refactors and crash in two places:

1. Checkpoint save crashes with `AttributeError: 'list' object has no
   attribute 'keys'` because the remote `modeling_nanbeige.py` declares
   `_tied_weights_keys` as List[str], but transformers>=5.x refactored
   tied-weights handling to expect Dict[str, str] (target -> source) and
   calls `.keys()` on it in `remove_tied_weights_from_state_dict`.

2. Standalone `from_pretrained` (e.g. test_embed.py) crashes with
   `KeyError: 'type'` because the remote `_init_rope` reads
   `rope_scaling['type']`, but transformers>=5.x injects
   `{'rope_type': 'default', ...}` (renamed key).

Fixes:
- `patcher.py`: add two compatibility shims in `patch_config` and
  `patch_model` that normalize rope_scaling (rope_type -> type / None)
  and convert `_tied_weights_keys` from list to dict at model load time.
  Both shims are guarded by `model_type == 'nanbeige'` and become no-ops
  once upstream Nanbeige ships transformers>=5.x-compatible remote code.
- `scripts/patch_nanbeige_remote_code.py`: one-shot idempotent patcher
  for the cached remote code on GPU clusters, fixing standalone scripts
  that bypass LlamaFactory (e.g. test_embed.py). Patches
  modeling_nanbeige.py (tied_weights + _init_rope) and
  configuration_nanbeige.py (_rope_scaling_validation), clears
  __pycache__.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@4teven

4teven commented Jul 25, 2026

Copy link
Copy Markdown
Author

Follow-up fix: Nanbeige4.2 remote code vs transformers>=5.x

While running training on the production GPU cluster, two crashes showed up that are not bugs in LlamaFactory itself, but incompatibilities between Nanbeige4.2's trust_remote_code files and the transformers>=5.x refactors.

Problem 1: checkpoint save crashes

AttributeError: 'list' object has no attribute 'keys'
  at remove_tied_weights_from_state_dict -> _get_tied_weight_keys

The remote modeling_nanbeige.py declares _tied_weights_keys as List[str] (old convention). transformers>=5.x refactored tied-weights handling to expect Dict[str, str] (target -> source) and calls .keys() on it during remove_tied_weights_from_state_dict, so every checkpoint save crashes.

Problem 2: standalone from_pretrained crashes

KeyError: 'type'
  at NanbeigeAttention._init_rope -> scaling_type = self.config.rope_scaling["type"]

The remote _init_rope reads rope_scaling["type"], but transformers>=5.x injects {"rope_type": "default", ...} (renamed key). This breaks standalone scripts like test_embed.py that call AutoModelForCausalLM.from_pretrained directly.

Fixes in this commit

  • src/llamafactory/model/patcher.py: two compatibility shims guarded by model_type == "nanbeige".
    • patch_config: normalizes rope_scaling (rope_type -> type / None) at model load time.
    • patch_model: converts _tied_weights_keys from list to dict at model load time.
  • scripts/patch_nanbeige_remote_code.py: one-shot idempotent patcher for the cached remote code on GPU clusters, for standalone scripts that bypass LlamaFactory.

Note

These shims are workarounds for outdated trust_remote_code and will become no-ops once the upstream Nanbeige HF repo (Nanbeige/Nanbeige4.2-3B) ships transformers>=5.x-compatible remote code (_tied_weights_keys as dict, _init_rope reading rope_type). Each shim is annotated with this context so it can be removed cleanly later.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant