Skip to content

Read rope_theta from rope_parameters in the Llama injection policy - #8341

Open
alanhuangyoo wants to merge 1 commit into
deepspeedai:masterfrom
alanhuangyoo:fix/llama-injection-rope-parameters
Open

Read rope_theta from rope_parameters in the Llama injection policy#8341
alanhuangyoo wants to merge 1 commit into
deepspeedai:masterfrom
alanhuangyoo:fix/llama-injection-rope-parameters

Conversation

@alanhuangyoo

@alanhuangyoo alanhuangyoo commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Fixes #8340.

What breaks

DS_LLAMAContainer.create_module resolves rope_theta as:

if hasattr(self.policy.client_module.self_attn, 'config'):
    _config.rope_theta = self.policy.client_module.self_attn.config.rope_theta
else:
    _config.rope_theta = self.policy.client_module.self_attn.rope_theta

transformers 5.0 folded the rotary settings into config.rope_parameters and dropped the attribute. LlamaAttention still has .config, so the first branch is taken and it raises.

This is not specific to the DeepSeek checkpoint in the issue — on transformers >= 5.0 it reproduces with a default LlamaConfig. Checked on 5.8.0:

transformers 5.8.0
LlamaConfig().rope_theta        -> AttributeError
LlamaConfig().rope_parameters   -> {'rope_theta': 10000.0, 'rope_type': 'default'}

and against a real module, both branches are dead:

self_attn has .config                 True
self_attn has .rope_theta             False
self_attn.config has rope_theta       False
self_attn.config has rope_parameters  True

current code -> AttributeError: 'LlamaConfig' object has no attribute 'rope_theta'

The fix

Try the old spellings first, then rope_parameters['rope_theta'], so pre-5.0 installs take exactly the path they take today and nothing changes for them.

This is the same drift #7443 adapted to. The num_heads accessor it fixed alongside still resolves on 5.8 (config.num_attention_heads is intact), so rope_theta is the only one that moved again.

requirements-dev.txt asks for transformers>=4.51.3 with no upper bound, so 5.x is in range.

Verified that rope_theta is the only accessor that moved: against a real LlamaDecoderLayer on 5.8.0, get_hidden_heads(), attention(), mlp() and layernorm() all resolve once this one is fixed.

I exercised the policy and container layer, not a full init_inference() run against a downloaded checkpoint on GPU.

Test

tests/unit/module_inject/test_llama_rope_theta.py covers the three layouts plus the precedence between them and the not-found case — CPU only, no model download:

6 passed

End to end against a real LlamaAttention on 5.8.0:

current code   AttributeError: 'LlamaConfig' object has no attribute 'rope_theta'
with this PR   10000.0
tests/unit/module_inject/    43 passed
yapf --diff / flake8         clean

I did not touch inference/v2. Six of its model implementations read self._config.rope_theta directly and exaone4 is the only one using a getattr default, so they likely have the same exposure — but that is a different engine and a different change, and I have not reproduced it.

Kernel injection resolves rope_theta as

    if hasattr(self.policy.client_module.self_attn, 'config'):
        _config.rope_theta = ...self_attn.config.rope_theta
    else:
        _config.rope_theta = ...self_attn.rope_theta

transformers 5.0 folded the rotary settings into config.rope_parameters
and dropped the attribute, so against a stock LlamaConfig both branches
raise. The first is taken -- LlamaAttention still has .config -- and
injection dies with

    AttributeError: 'LlamaConfig' object has no attribute 'rope_theta'

On transformers 5.8.0 that reproduces with a default LlamaConfig, so it
is not specific to the DeepSeek checkpoint in deepspeedai#8340.

Fall back to rope_parameters['rope_theta'] when the attribute is gone,
keeping the old spellings first so pre-5.0 installs are unaffected. This
is the same drift deepspeedai#7443 adapted to; the num_heads accessor it fixed
alongside still resolves, so only this one moved.

Fixes deepspeedai#8340

Signed-off-by: alanhuangyoo <alanhuangyoo@gmail.com>
@alanhuangyoo

Copy link
Copy Markdown
Contributor Author

Opened #8345 for the inference/v2 exposure I flagged at the bottom of this description — separate engine, separate change, so I kept it out of here.

It turned out to be eight models, and one of them fails quietly rather than loudly: exaone4 reads the base through getattr(self._config, "rope_theta", 1000000.0), and Exaone4Config carries rope_parameters["rope_theta"] == 10000.0, so on 5.x it puts a 100x rotary base into RotateHalfConfig with nothing raised.

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.

[BUG] DeepSpeed kernel injection crashes on a DeepSeek configuration without rope_theta

1 participant