Repository navigation
[feat] Load Kimi K3 weights from object storage with Model Streamer - #21651
Draft
benamizilberNvidia wants to merge 14 commits into
Draft
benamizilberNvidia wants to merge 14 commits into
benamizilberNvidia wants to merge 14 commits into
Conversation
Use a new str enum CheckpointIOPolicy for better code readability and maintenance. Public API and telemetry are updated accordingly. Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Use a new str enum CheckpointFormat for built-in checkpoint formats like "HF", "MX" and "mistral". Custom 3rd-party formats are still accepted as str. This improves code readability and maintenance. Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
tighten function parameter load_format type range from LoadFormat | str to LoadFormat. This is dead code as the upstream functions don't use checkpoint loading helper functions with str load formats. Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Refactor the function that generates checkpoint io policy fallback/error reason so it's easier for humans to read. Also rename _construct_checkpoint_loader to construct_checkpoint_loader since it's used outside the file defining it. Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
To reduce the complex code in model_loader.py, created new files to hold helper functions: - tensorrt_llm/_torch/models/checkpoints/gms/model_loading.py - tensorrt_llm/_torch/models/checkpoints/mx/model_loading.py - tensorrt_llm/_torch/models/checkpoints/memory_init.py - tensorrt_llm/_torch/models/checkpoints/model_hooks.py Refactor ModelLoader.load() to be more compact and simpler to understand. Create private helper functions in model_loader.py to hold load_format=auto loading path, which includes the HF loading, the rank-striped-read-ahead loading and custom checkpoint loading options. Remove an old duplicate doc docs/source/torch/features/checkpoint_loading.md. Clean up the checkpoint loading doc docs/source/features/checkpoint-loading.md: - Add missing checkpoint format. - Simplify explanation. - Remove extra details most users don't need to know. Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Move the weight-loading methods of KimiLinearForCausalLM and the helpers that only they use into the new file modeling_kimi_k3_loader.py. modeling_kimi_linear.py had over 3,300 lines, and about 1,100 of them only turn checkpoint tensors into model parameters. The code moves unchanged: KimiLinearForCausalLM inherits the methods from KimiK3WeightLoaderMixin, and tests import the moved helpers from the new file. The inference module _Fp8BlockScaleWeightReadLinear stays in modeling_kimi_linear.py; the loader imports it inside the functions that use it, because modeling_kimi_linear.py imports the loader. No functional change. Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Add checkpoint_io_policy="model_streamer", which loads a Hugging Face checkpoint with Run:ai Model Streamer. Model Streamer reads each byte from storage once per node and shares it among the ranks of the node, so large checkpoints load faster. A model describes what it needs in plan_model_streamer_load(), which returns a ModelStreamerPlan: groups of checkpoint tensor names, each with a function that loads the group. The new models/checkpoints/model_streamer/model_loading.py streams only the tensors that the ranks of a node need, with run_model_streamer(), and loads each group as soon as its tensors arrive. A separate draft checkpoint, such as a DSpark drafter, is read with the regular checkpoint reader. The next commit adds this for Kimi K3. Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Implement plan_model_streamer_load() for Kimi K3 and its multimodal wrapper, with the ModelStreamerPlan from the previous commit. Each rank lists only the tensors that it needs, for example its own experts, so each node streams only what its ranks use. Also support Kimi K3 language-only loads that skip the multimodal encoder, document Model Streamer loading in the Kimi K3 README, and add tests. Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Add llmapi/object_storage.py for loading a model from an s3://, gs:// or az:// URI. It detects object-storage URIs and copies the files that Hugging Face loaders read from local disk (config, tokenizer, remote code, not the weights) into a node-local cache directory named after a hash of the URI. A .runai_complete marker makes later pulls no-ops, and concurrent processes on a node wait for the first one. TRTLLM_OBJECT_STORAGE_FORCE_PULL=1 downloads the files again once per launch. Add the unit tests to the CPU test list. Signed-off-by: Ben Ami Zilber <bzilber@nvidia.com>
An object-storage model needs checkpoint_io_policy="model_streamer"; any other policy raises before anything is downloaded. A draft model or LoRA directory on object storage is rejected, a local one is allowed. The config, generation config and tokenizer are read from the local metadata copy, which this change pulls once per node: - llm_args: the tokenizer validator loads a given tokenizer from the copy. - llm_utils: CachedModelLoader pulls the metadata on the local rank 0 of each node. - llm: the HF config, the generation config and the default tokenizer use the local copy instead of the URI. Signed-off-by: Ben Ami Zilber <bzilber@nvidia.com>
ModelLoader hands the object-storage URI, and the local metadata directory, to Model Streamer instead of the local checkpoint directory. The streamer's tensor source map reads model.safetensors.index.json from the local copy and maps each tensor to its file URI in the bucket. A separate draft checkpoint is still read from a local path with the checkpoint loader. Signed-off-by: Ben Ami Zilber <bzilber@nvidia.com>
Describe the URI forms, the required model_streamer policy, the metadata cache and its force-pull option, and the limits (Kimi K3 only, an index file is required, no draft model or LoRA on object storage) in the Kimi K3 README and the checkpoint loading guide. Signed-off-by: Ben Ami Zilber <bzilber@nvidia.com>
Declare the runai-model-streamer dependency as an optional extra, as the mx extra does for modelexpress: runai-model-streamer[s3,gcs,azure]>=0.17.0. The 0.17.0 floor is the release that adds the tensor_names and owned arguments of SafetensorsStreamer; the extras install the readers for s3://, gs:// and az://. Tell users to install it in the checkpoint loading guide and the Kimi K3 README. Signed-off-by: Ben Ami Zilber <bzilber@nvidia.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@coderabbitai summary
Description
Stacked on #20782. This branch contains the 9 commits of #20782 plus 5 commits of its own. Until #20782 merges, review only the last 5 commits: compare view. Once #20782 merges, I will rebase onto
mainand the PR shows only those 5 commits. It is a draft until then. The conflict withmain(modeling_kimi_linear.py) comes from #20782, not from these commits.With
checkpoint_io_policy: model_streamer,--modelcan be ans3://,gs://oraz://URI. The weights stream from the bucket through Run:ai Model Streamer and are never copied to local disk.The 5 commits:
Add object storage helpers for model metadata: newllmapi/object_storage.py. It detects object-storage URIs and copies the files that Hugging Face loaders read from local disk (config, tokenizer, remote code, not the weights) into a node-local cache directory named after a hash of the URI. A.runai_completemarker makes later pulls no-ops, and concurrent processes on a node wait for the first one.TRTLLM_OBJECT_STORAGE_FORCE_PULL=1downloads the files again once per launch.Accept object-storage model URIs in the LLM API: an object-storage model requirescheckpoint_io_policy="model_streamer"and any other policy raises before anything is downloaded. A draft model or LoRA directory on object storage is rejected, a local one is allowed. The config, generation config and tokenizer are read from the local metadata copy, pulled once per node by local rank 0.Stream Kimi K3 weights from object storage:ModelLoaderhands the URI, and the local metadata directory, to Model Streamer. The streamer's tensor source map readsmodel.safetensors.index.jsonfrom the local copy and maps each tensor to its file URI in the bucket.Document loading Kimi K3 from object storage: the URI forms, the required policy, the metadata cache and its force-pull option, and the limits, in the Kimi K3 README and the checkpoint loading guide.Add a runai extra for loading from object storage: a new optional extra insetup.py,runai = ["runai-model-streamer[s3,gcs,azure]>=0.17.0"], in the style of themxextra. The 0.17.0 floor is the release that adds thetensor_namesandownedarguments ofSafetensorsStreamer. Thes3,gcsandazureextras install the readers fors3://,gs://andaz://. The README and the guide tell users topip install "tensorrt_llm[runai]". This is a new optional dependency, so it needs the license and vulnerability scan from the checklist.Limits: Kimi K3 only, the checkpoint needs an index file, and no draft model or LoRA on object storage.
Test Coverage
tests/unittest/llmapi/test_object_storage.py(new, added to thel0_cpulist): URI detection, metadata pull, completion marker, concurrent pulls, force pull.tests/unittest/llmapi/test_llm_args.pyandtest_llm_utils.py: policy validation, draft model and LoRA rules, metadata pull on local rank 0.tests/unittest/_torch/pyexecutor/test_model_loader_checkpoint_io.py: the URI and metadata directory reach Model Streamer.Not run yet on this rebased branch: the unit tests above (the changed Python files compile). The rebase onto the current #20782 head had conflicts in
l0_cpu.ymland the Kimi K3 README, resolved by hand. CI will exercise the tests.PR Checklist
Please review the following before submitting your PR:
PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.
PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.
Test cases are provided for new code paths (see test instructions)
If PR introduces API changes, an appropriate PR label is added - either
api-compatibleorapi-breaking. Forapi-breaking, includeBREAKINGin the PR title.Any new dependencies have been scanned for license and vulnerabilities
CODEOWNERS updated if ownership changes
Documentation updated as needed
Update tava architecture diagram if there is a significant design change in PR.
The reviewers assigned automatically/manually are appropriate for the PR.
Please check this after reviewing the above items as appropriate for this PR.
GitHub Bot Help
To see a list of available CI bot commands, please comment
/bot help.