Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add new model: Kimi2-6#45630

Merged
vasqu merged 68 commits into
huggingface:mainfrom
zucchini-nlp:kimi
Jul 3, 2026
Merged

Add new model: Kimi2-6#45630
vasqu merged 68 commits into
huggingface:mainfrom
zucchini-nlp:kimi

Conversation

@zucchini-nlp

@zucchini-nlp zucchini-nlp commented Apr 24, 2026

Copy link
Copy Markdown
Member

CI

What does this PR do?

The moonshot team is not very active and haven't yet replied, so I kept all the model_type naming to match the remote code. That allows us to load a model with local code. There are still a few problems such as tokenizer needing conversion and jinja chat template being non-consistent though

They have saved a tiktoken tokeninzer and tbh I am not sure if we can convert it, and nudge them to update. So as a workaround we convert from tiktoken at load-time

Tested with below script but uses a smaller/dummy model. Logits and eager generation are equivalent with official implementation.

import torch
from transformers import AutoProcessor, AutoTokenizer, AutoModelForImageTextToText

processor = AutoProcessor.from_pretrained('moonshotai/Kimi-K2.6', trust_remote_code=False)
model = AutoModelForImageTextToText.from_pretrained(
    'moonshotai/Kimi-K2.6',
    dtype=torch.bfloat16,
    device_map="cuda:0",
    trust_remote_code=False,
    attn_implementation="eager",
)


messages = [
    {
        "role": "user",
        "content": [
            {"type": "image", "image": "image.png"},
            # {"type": "video", "video_url":{"url"  "video.mp4"}}, # note that videos need different layout due to jinja template
            {"type": "text", "text": "What is shown in this image?"},
        ],
    }
]

inputs = processor.apply_chat_template(
    messages,
    tokenize=True,
    add_generation_prompt=True,
    return_tensors="pt",
    return_dict=True,
).to(device=model.device, dtype=torch.bfloat16)

generated_ids = model.generate(**inputs, max_new_tokens=64)
generated_text = processor.batch_decode(generated_ids[:, inputs["input_ids"].shape[-1]:], skip_special_tokens=True)[0]
print(generated_text)

@zucchini-nlp

Copy link
Copy Markdown
Member Author

Oke, I think the model part looks same as the custom code, though I didn't test it. Also we need to check what is the exact chat template format and how to add placeholder tokens per modality, again with the real checkpoint

Kimi team might reply on Monday, coming back then

@vasqu vasqu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial comments from my side, I wanted to focus on things that we could simplify - mainly the RoPE I think.

I know it's WIP in a way so don't mind comments you already want to address yourself

Comment thread docs/source/en/model_doc/kimi2_6.md Outdated
Comment thread docs/source/en/model_doc/kimi2_6.md Outdated
Comment thread src/transformers/models/auto/image_processing_auto.py Outdated
Comment thread src/transformers/models/auto/tokenization_auto.py Outdated
Comment thread src/transformers/models/auto/tokenization_auto.py Outdated
Comment thread src/transformers/models/kimi_k25/modular_kimi_k25.py
Comment thread src/transformers/models/kimi_k25/modular_kimi_k25.py
Comment thread src/transformers/conversion_mapping.py
Comment thread src/transformers/core_model_loading.py Outdated
Comment thread src/transformers/core_model_loading.py Outdated
Comment on lines +586 to 623
if image_processor_type is None:
try:
if not isinstance(config, PreTrainedConfig):
config = AutoConfig.from_pretrained(
pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs
)

image_processor_type = getattr(config, "image_processor_type", None)
if hasattr(config, "auto_map") and "AutoImageProcessor" in config.auto_map:
image_processor_auto_map = config.auto_map["AutoImageProcessor"]
except ValueError:
# Config loading failed (unrecognized model_type, invalid config, etc.)
# Continue to fallback logic below (AutoTokenizer, AutoImageProcessor, etc.)
pass

# Derive base_class_name from image_processor_type
is_legacy_fast = False
base_class_name = None
if image_processor_type is not None:
is_legacy_fast = image_processor_type.endswith("Fast")
base_class_name = image_processor_type[:-4] if is_legacy_fast else image_processor_type

backend = _resolve_backend(backend_kwarg, use_fast, base_class_name)

image_processor_class = None
if base_class_name is not None:
image_processor_class = _load_backend_class(base_class_name, backend, is_legacy_fast)

# Handle remote code
has_remote_code = image_processor_auto_map is not None
has_local_code = image_processor_class is not None or type(config) in IMAGE_PROCESSOR_MAPPING
explicit_local_code = has_local_code and not (
image_processor_class or _load_class_with_fallback(IMAGE_PROCESSOR_MAPPING[type(config)], backend)
).__module__.startswith("transformers.")
if has_remote_code:
class_ref = _resolve_auto_map_class_ref(image_processor_auto_map, backend)
upstream_repo = class_ref.split("--")[0] if "--" in class_ref else None
trust_remote_code = resolve_trust_remote_code(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copied from processing_auto.pt btw. The idea is to infer local class name if possible from config, even if we found a remote code

The remote code will still be loaded with higher prio if users pass trust_remote_code, so nothing should break

Comment on lines +151 to +155
@requires(
backends=[
"torch",
]
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm why is this needed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it requires torch :)

The repo consistency isn't happy and tries to import it with no-torch env, then it raises error

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oke, maybe this folder is supposed to be non-torch. I see FP conversions are in root/integrations/

Comment thread src/transformers/models/kimi_k25/modular_kimi_k25.py Outdated
@vasqu

vasqu commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

run-slow: kimi_k25

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Workflow Run ⚙️

This comment contains run-slow, running the specified jobs:

models: ["models/kimi_k25"]
quantizations: []

Comment on lines +496 to +509
outputs = []
running_length = 0
for t, h, w in grid_thw.tolist():
# Get the current sequence
seq = hidden_states[running_length : running_length + t * h * w]
# Reshape along self.merge_kernel_size and concat to the last dimension
new_height, new_width = h // kernel_height, w // kernel_width
reshaped_seq = seq.view(t, new_height, kernel_height, new_width, kernel_width, hidden_dim)
reshaped_seq = reshaped_seq.transpose(2, 3).mean(dim=0) # temporal pooling
padded_seq = reshaped_seq.reshape(new_height * new_width, kernel_height * kernel_width, -1)
outputs.append(padded_seq)
running_length += t * h * w

return torch.cat(outputs, dim=0)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please use the compile/export friendly vision_utils here 🙏

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no utility to permute and pooling each image, no?

@IlyasMoutawwakil IlyasMoutawwakil self-requested a review July 3, 2026 11:59
@huggingface huggingface deleted a comment from github-actions Bot Jul 3, 2026
Comment thread docs/source/en/model_doc/kimi_k25.md Outdated
@vasqu

vasqu commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

run-slow: kimi_k25

@zucchini-nlp

Copy link
Copy Markdown
Member Author

run-slow: kimi_k25

1 similar comment
@zucchini-nlp

Copy link
Copy Markdown
Member Author

run-slow: kimi_k25

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Workflow Run ⚙️

This comment contains run-slow, running the specified jobs:

models: ["models/kimi_k25"]
quantizations: []

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

CI Results

Workflow Run ⚙️

Commit Info

Context Commit Description
RUN 487da00f workflow commit (merge commit)
PR 0a1fcd4d branch commit (from PR)
main 5d063058 base commit (on main)

Model CI Report

4 new failed tests from this PR 😭

  • kimi_k25:
    tests/models/kimi_k25/test_modeling_kimi_k25.py::Kimi_K25ModelTest::test_generate_compilation_all_outputs (✅ ⟹ ❌)
    tests/models/kimi_k25/test_modeling_kimi_k25.py::Kimi_K25ModelTest::test_generate_compile_model_forward_fullgraph (✅ ⟹ ❌)
    tests/models/kimi_k25/test_modeling_kimi_k25.py::Kimi_K25ModelTest::test_generate_from_inputs_embeds_with_static_cache (✅ ⟹ ❌)
    tests/models/kimi_k25/test_modeling_kimi_k25.py::Kimi_K25ModelTest::test_generate_with_static_cache (✅ ⟹ ❌)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it was not reverted?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, weird, it didn't get reverted

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

CI recap

Dashboard: View test results in Grafana
Latest run: 28667688910:1
Result: failure | Jobs: 15 | Tests: 171,114 | Failures: 1 | Duration: 25h 54m

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

[For maintainers] Suggested jobs to run (before merge)

run-slow: auto, kimi_k25

@vasqu vasqu merged commit 0983570 into huggingface:main Jul 3, 2026
99 of 100 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants