Image-to-Video
Cosmos
Diffusers
Safetensors
cosmos3_omni
nvidia
cosmos3
video-generation
nvfp4
quantized
modelopt
Instructions to use prometheusAIR/Cosmos3-Super-Image2Video-4Step-NVFP4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Cosmos
How to use prometheusAIR/Cosmos3-Super-Image2Video-4Step-NVFP4 with Cosmos:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
Upload folder using huggingface_hub
Browse files- .gitattributes +5 -0
- BIAS.md +11 -0
- EXPLAINABILITY.md +16 -0
- LICENSE +49 -0
- PRIVACY.md +6 -0
- README.md +187 -0
- SAFETY.md +11 -0
- assets/example_first_frame.png +3 -0
- assets/example_output.mp4 +3 -0
- assets/example_prompt.json +1 -0
- assets/original_prompt.txt +1 -0
- chat_template.json +3 -0
- checkpoint.json +5 -0
- config.json +252 -0
- generation_config.json +14 -0
- images/aa-i2v-all-models-2026-07-17.png +3 -0
- images/aa-i2v-open-models-2026-07-17.png +3 -0
- load_cosmos3_modelopt.py +256 -0
- merges.txt +0 -0
- model.safetensors.index.json +0 -0
- model_index.json +28 -0
- modular_model_index.json +64 -0
- preprocessor_config.json +21 -0
- quantize_cosmos3_i2v4step_streaming.py +383 -0
- repackage_for_hf_i2v4step.py +97 -0
- scheduler/scheduler_config.json +28 -0
- scripts/gen_video.py +76 -0
- scripts/upsample_prompt.py +168 -0
- serve_cosmos3_i2v4step_diffusers.py +449 -0
- text_tokenizer/added_tokens.json +28 -0
- text_tokenizer/chat_template.jinja +120 -0
- text_tokenizer/merges.txt +0 -0
- text_tokenizer/special_tokens_map.json +31 -0
- text_tokenizer/tokenizer.json +3 -0
- text_tokenizer/tokenizer_config.json +239 -0
- text_tokenizer/vocab.json +0 -0
- tokenizer.json +0 -0
- tokenizer_config.json +239 -0
- transformer/config.json +43 -0
- transformer/diffusion_pytorch_model-00001-of-00004.safetensors +3 -0
- transformer/diffusion_pytorch_model-00002-of-00004.safetensors +3 -0
- transformer/diffusion_pytorch_model-00003-of-00004.safetensors +3 -0
- transformer/diffusion_pytorch_model-00004-of-00004.safetensors +3 -0
- transformer/diffusion_pytorch_model.safetensors.index.json +0 -0
- transformer/modelopt_state.pth +3 -0
- vae/config.json +129 -0
- vae/diffusion_pytorch_model.safetensors +3 -0
- validate_cosmos3_i2v4step_fp8.py +77 -0
- video_preprocessor_config.json +21 -0
- vocab.json +0 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
text_tokenizer/tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
assets/example_first_frame.png filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
assets/example_output.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
images/aa-i2v-all-models-2026-07-17.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
images/aa-i2v-open-models-2026-07-17.png filter=lfs diff=lfs merge=lfs -text
|
BIAS.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## Bias
|
| 2 |
+
|
| 3 |
+
| Field | Response |
|
| 4 |
+
| :---- | :---- |
|
| 5 |
+
| Participation considerations from adversely impacted groups [protected classes](https://www.senate.ca.gov/content/protected-classes) in model design and testing | None. |
|
| 6 |
+
| Measures taken to mitigate against unwanted bias | Training, evaluation, and testing data are curated before release to filter restricted content, including content relating to protected classes. Model behavior is evaluated across Physical AI domains — robotics, autonomous vehicles, human-centric scenes, common scenes, industry, miscellaneous, and physics-oriented benchmarks — with attention to coverage across diverse demographic and contextual characteristics that affect protected-class outcomes. |
|
| 7 |
+
| Which characteristic (feature) show(s) the greatest difference in performance?: | Greatest performance differences are observed in tasks requiring long-horizon temporal consistency, fine-grained physical interactions, and embodiment-specific action generation. Performance is generally stronger on common visual reasoning and world-generation tasks than on complex multi-agent, robotics-control, or tightly synchronized multimodal generation scenarios. |
|
| 8 |
+
| Which feature(s) have the worst performance overall? | Performance is generally weakest in tasks requiring long-horizon temporal consistency, precise physical interactions, embodiment-specific action control, and strict audio-visual synchronization. |
|
| 9 |
+
| If using internal data, description of methods implemented in data acquisition or processing, if any, to address the prevalence of identifiable biases in the training, testing, and validation data: | Bias-specific methods applied during data processing include person-presence screening, demographic-taxonomy classification (age, gender, ethnicity), embedding-based diversity analysis, and dataset balancing across sources. Internal analysis surfaced: non-person scenes are more prevalent than person-centric content; demographic-taxonomy outputs on person-present samples are most frequently "uncertain" across age, gender, and ethnicity dimensions; and source-type variation, with people-centric image and video datasets showing higher demographic signal than document-, object-, robotics-, or scene-focused datasets. *(Quantitative details in the row below.)* Downstream deployments should add bias audits, fairness evaluation, red-teaming, demographically balanced fine-tuning, or counterfactual augmentation as mitigations. |
|
| 10 |
+
| Tools used to assess statistical imbalances and highlight patterns that may introduce bias into AI models: | Dataset analytics pipelines, metadata distribution analysis, heuristic quality checks, embedding-based clustering, model-assisted filtering systems, and benchmark evaluation suites are used to assess statistical imbalances and identify patterns that may introduce bias into model behavior. |
|
| 11 |
+
| Tools used to assess statistical imbalances and highlight patterns that may introduce bias into AI models: | These datasets, such as OpenImages-derived detection-to-NLP datasets, visual grounding and VQA datasets, document/image understanding datasets, video/action understanding datasets, and NVIDIA-created or curated visual datasets, do not collectively or exhaustively represent all demographic groups (and proportionally therein). For instance, automated person-presence screening did not identify a person in approximately 58% of visual samples analyzed across approximately 400 datasets, while person-present signals were identified in approximately 42% of analyzed samples. In the subset where person-present signals were identified, these datasets contain uneven representation splits across the measured visual taxonomies: age outputs were most frequently uncertain, followed by child and adult; gender outputs were most frequently uncertain, followed by male and female; and ethnicity outputs were most frequently uncertain, followed by Hispanic and White as the most frequent identified categories. Dataset-level results vary by source type, with people-centric image and video datasets containing higher person-present and demographic-taxonomy signals than document-, object-, robotics-, or scene-focused datasets. To mitigate these imbalances, we recommend considering evaluation techniques such as bias audits, task-specific fairness evaluation, and red-teaming, along with fine-tuning with demographically balanced datasets and counterfactual data augmentation to align with the desired model behavior. This evaluation used a baseline of 200 samples across all datasets, with larger subsets of up to 3,000 samples utilized for certain in-depth analyses, identified as optimal thresholds for maximizing embedder accuracy. |
|
EXPLAINABILITY.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## Explainability
|
| 2 |
+
|
| 3 |
+
| Field | Response |
|
| 4 |
+
| :---- | :---- |
|
| 5 |
+
| Intended Application & Domain | World reasoning and generation for Physical AI. |
|
| 6 |
+
| Model Type | Mixture-of-Transformers architecture with two towers. One is an autoregressive model for Physical AI reasoning; the other is a diffusion model for Physical AI generation. |
|
| 7 |
+
| Intended Users | Physical AI developers, researchers, and practitioners building or evaluating autonomous vehicle, robotics, and world-generation workflows. |
|
| 8 |
+
| Output | Images, videos, audio, and action commands. |
|
| 9 |
+
| Tools used to evaluate datasets to identify synthetic data and ensure data authenticity. | Dataset provenance analysis, metadata validation, watermark and artifact detection, embedding-based clustering, heuristic quality checks, and model-assisted data validation pipelines are used to identify synthetic content patterns, assess dataset authenticity, and improve data quality during dataset curation. |
|
| 10 |
+
| Describe how the model works | Cosmos3 is an Omni world foundation model that generates texts, images, videos, audio, and action commands from combinations of text, images, videos, and action trajectory inputs. Input tokens from multiple modalities are packed into a shared sequence and processed by our mixture-of-transformer backbone with modality-specific output heads. |
|
| 11 |
+
| Name the adversely impacted groups this has been tested to deliver comparable outcomes regardless of: | None. |
|
| 12 |
+
| Technical Limitations | The model may not follow text, image, video, audio, or action trajectory inputs accurately in challenging cases, especially where the input contains complex scene composition, unusual camera motion, multiple interacting agents, low lighting, high motion blur, or fine-grained physical interactions. Generated outputs may contain temporal inconsistency, object morphing, inaccurate 3D structure, or implausible physical dynamics. Generated audio may not accurately render intelligible speech, or maintain strict temporal and semantic alignment with the visual context. |
|
| 13 |
+
| Verified to have met prescribed NVIDIA quality standards | Yes. |
|
| 14 |
+
| Performance Metrics | Video generation is measured using PAIBench-G, RBench, PhysicsIQ, and Artifical Analysis Image2Video benchmark. Image generation uses UniGenBench and Artifical Analysis Text2Image benchmark. For transfer evaluation, we use PAIBench-C and AVBench-C. Audio generation uses internal benchmarks. Action prediction uses metrics such as action MSE, Absolute Translation Error, Relative Translation Error, Relative Rotation Error, PSNR, and robotic task completion success rate. |
|
| 15 |
+
| Potential Known Risks | This model can generate synthetic media and may produce content that is offensive, unsafe, misleading, indecent, or unsuitable for a target deployment. Users should implement robust safety guardrails — including content filtering, abuse monitoring, and access controls — to reduce the risk of harmful outputs. Users are responsible for ensuring that their use of the model complies with all applicable laws and regulations, and for regularly reviewing and updating their guardrails as risks evolve. |
|
| 16 |
+
| Licensing | [OpenMDW1.1](https://openmdw.ai/) |
|
LICENSE
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
OpenMDW License Agreement, version 1.1 (OpenMDW-1.1)
|
| 2 |
+
|
| 3 |
+
By exercising rights granted to you under this agreement, you accept and agree
|
| 4 |
+
to its terms.
|
| 5 |
+
|
| 6 |
+
As used in this agreement, "Model Materials" means the materials provided to
|
| 7 |
+
you under this agreement, consisting of: (1) one or more machine learning
|
| 8 |
+
models (including architecture and parameters); and (2) all related artifacts
|
| 9 |
+
(including associated data, documentation and software) that are provided to
|
| 10 |
+
you hereunder.
|
| 11 |
+
|
| 12 |
+
Subject to your compliance with this agreement, permission is hereby granted,
|
| 13 |
+
free of charge, to deal in the Model Materials without restriction, including
|
| 14 |
+
under all copyright, patent, database, and trade secret rights included or
|
| 15 |
+
embodied therein.
|
| 16 |
+
|
| 17 |
+
If you distribute any portion of the Model Materials, you shall retain in your
|
| 18 |
+
distribution (1) a copy of this agreement, and (2) all copyright notices and
|
| 19 |
+
other notices of origin included in the Model Materials that are applicable to
|
| 20 |
+
your distribution.
|
| 21 |
+
|
| 22 |
+
If you file, maintain, or voluntarily participate in a lawsuit against any
|
| 23 |
+
person or entity asserting that the Model Materials directly or indirectly
|
| 24 |
+
infringe any patent or copyright, then all rights and grants made to you
|
| 25 |
+
hereunder are terminated, unless that lawsuit was in response to a
|
| 26 |
+
corresponding lawsuit first brought against you.
|
| 27 |
+
|
| 28 |
+
This agreement does not impose any restrictions or obligations with respect to
|
| 29 |
+
any use, modification, or sharing of any outputs generated by using the Model
|
| 30 |
+
Materials.
|
| 31 |
+
|
| 32 |
+
THE MODEL MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
| 33 |
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 34 |
+
FITNESS FOR A PARTICULAR PURPOSE, TITLE, NONINFRINGEMENT, ACCURACY, OR THE
|
| 35 |
+
ABSENCE OF LATENT OR OTHER DEFECTS OR ERRORS, WHETHER OR NOT DISCOVERABLE, ALL
|
| 36 |
+
TO THE GREATEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW.
|
| 37 |
+
|
| 38 |
+
YOU ARE SOLELY RESPONSIBLE FOR (1) CLEARING RIGHTS OF OTHER PERSONS THAT MAY
|
| 39 |
+
APPLY TO THE MODEL MATERIALS OR ANY USE THEREOF, INCLUDING WITHOUT LIMITATION
|
| 40 |
+
ANY PERSON'S COPYRIGHTS OR OTHER RIGHTS INCLUDED OR EMBODIED IN THE MODEL
|
| 41 |
+
MATERIALS; (2) OBTAINING ANY NECESSARY CONSENTS, PERMISSIONS OR OTHER RIGHTS
|
| 42 |
+
REQUIRED FOR ANY USE OF THE MODEL MATERIALS; OR (3) PERFORMING ANY DUE
|
| 43 |
+
DILIGENCE OR UNDERTAKING ANY OTHER INVESTIGATIONS INTO THE MODEL MATERIALS OR
|
| 44 |
+
ANYTHING INCORPORATED OR EMBODIED THEREIN.
|
| 45 |
+
|
| 46 |
+
IN NO EVENT SHALL THE PROVIDERS OF THE MODEL MATERIALS BE LIABLE FOR ANY CLAIM,
|
| 47 |
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
| 48 |
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MODEL MATERIALS, THE
|
| 49 |
+
USE THEREOF OR OTHER DEALINGS THEREIN.
|
PRIVACY.md
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## Privacy
|
| 2 |
+
| Privacy Information |
|
| 3 |
+
|---|
|
| 4 |
+
| The model was trained on large-scale publicly available data that may contain images, audio-video, and text relating to people. NVIDIA collected and used this data in compliance with applicable data protection and privacy laws. This model was not designed to derive insights or otherwise learn from any personal data contained in the datasets. |
|
| 5 |
+
| NVIDIA uses a combination of filters, data minimization techniques, and other guardrails to help prevent personal data from being recited by our models. We employ automated tools and data processing techniques during pre-training or training to identify and filter certain categories of personal data. For example, for text-bearing source and document components, our automated tools identified potential personal data such as person names, locations, and possible business or public-facing contact information such as email addresses and phone numbers. We reviewed and removed any verified instances of personal data through a combination of automated filtering and human-in-the-loop validation. |
|
| 6 |
+
| Please review NVIDIA's [Privacy Policy](https://www.nvidia.com/en-us/about-nvidia/privacy-policy/) for more information. |
|
README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: other
|
| 3 |
+
license_name: openmdw1.1-license
|
| 4 |
+
license_link: >-
|
| 5 |
+
https://openmdw.ai/license/1-1/
|
| 6 |
+
library_name: cosmos
|
| 7 |
+
tags:
|
| 8 |
+
- nvidia
|
| 9 |
+
- cosmos
|
| 10 |
+
- cosmos3
|
| 11 |
+
- image-to-video
|
| 12 |
+
- video-generation
|
| 13 |
+
- nvfp4
|
| 14 |
+
- quantized
|
| 15 |
+
- modelopt
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
# Cosmos3-Super-Image2Video-4Step — NVFP4 (community quantization)
|
| 19 |
+
|
| 20 |
+
This is a community **NVFP4, weight-only** quantization of NVIDIA's
|
| 21 |
+
[`nvidia/Cosmos3-Super-Image2Video-4Step`](https://huggingface.co/nvidia/Cosmos3-Super-Image2Video-4Step) —
|
| 22 |
+
a 64B-parameter image-to-video model, DMD2-distilled for 4-step, CFG-free
|
| 23 |
+
generation — produced with [NVIDIA TensorRT Model Optimizer](https://github.com/NVIDIA/TensorRT-Model-Optimizer)
|
| 24 |
+
(`nvidia-modelopt`). A sibling of
|
| 25 |
+
[prometheusAIR/Cosmos3-Super-Image2Video-4Step-FP8](https://huggingface.co/prometheusAIR/Cosmos3-Super-Image2Video-4Step-FP8) —
|
| 26 |
+
this format trades a bit more quantization error for a much smaller footprint:
|
| 27 |
+
**~38GB resident vs FP8's ~66GB**, useful if you want headroom for longer clips,
|
| 28 |
+
higher resolutions, or running alongside other GPU workloads on the same card.
|
| 29 |
+
|
| 30 |
+
**Model Developer (original model): NVIDIA.** This is not an official NVIDIA
|
| 31 |
+
release. Everything about the model itself — architecture, training data,
|
| 32 |
+
benchmarks, full input/output specs, limitations, and ethical considerations —
|
| 33 |
+
is unchanged from NVIDIA's original and is documented on
|
| 34 |
+
[their model card](https://huggingface.co/nvidia/Cosmos3-Super-Image2Video-4Step);
|
| 35 |
+
it isn't reproduced here. This card only covers what we changed (the
|
| 36 |
+
quantization) and how to run *this* checkpoint.
|
| 37 |
+
|
| 38 |
+
## License
|
| 39 |
+
|
| 40 |
+
Released under the [OpenMDW-1.1](https://openmdw.ai/license/1-1/) license, same
|
| 41 |
+
as the original model — see [`LICENSE`](LICENSE) in this repo.
|
| 42 |
+
|
| 43 |
+
## Quantization Notes
|
| 44 |
+
|
| 45 |
+
**Recipe:** NVFP4 (E2M1 4-bit weights, block_size 16, FP8/E4M3 block scales +
|
| 46 |
+
an FP32 per-tensor scale) on the 64 transformer blocks' attention/MLP linears.
|
| 47 |
+
Activations, embeddings, norms, the bundled Qwen3 reasoner head,
|
| 48 |
+
`time_embedder`, and `proj_in`/`proj_out` are left in BF16. Weight-only, so no
|
| 49 |
+
calibration forward pass was needed — same recipe and same spared layers as
|
| 50 |
+
the FP8 sibling, just a smaller weight format. Per NVIDIA's own note, no
|
| 51 |
+
quantized precision is officially tested/supported for this model — treat
|
| 52 |
+
this as best-effort, and expect somewhat more quantization error than the
|
| 53 |
+
FP8 release given the lower bit-width.
|
| 54 |
+
|
| 55 |
+
**Loading gotchas — read before using with `diffusers`:** as of
|
| 56 |
+
`diffusers==0.39.0.dev0`, plain `Cosmos3OmniPipeline` usage has **two** bugs
|
| 57 |
+
against this checkpoint (identical to the FP8 release — same base checkpoint,
|
| 58 |
+
same diffusers version, unrelated to which quantization format you use). Both
|
| 59 |
+
are fixed automatically by the serving script below
|
| 60 |
+
(`serve_cosmos3_i2v4step_diffusers.py`); if you're writing your own loading
|
| 61 |
+
code, patch the scheduler yourself as shown.
|
| 62 |
+
|
| 63 |
+
1. **Wrong step count / CFG on.** `Cosmos3OmniPipeline.__call__` does not read
|
| 64 |
+
this checkpoint's `scheduler/scheduler_config.json` →
|
| 65 |
+
`fixed_step_sampler_config.t_list` (the trained 4-step sde schedule). It
|
| 66 |
+
silently falls back to the pipeline's generic defaults
|
| 67 |
+
(`num_inference_steps=35`, `guidance_scale=6.0`), which is off-distribution
|
| 68 |
+
for a DMD2-distilled 4-step checkpoint. (`vLLM-Omni` parses this file
|
| 69 |
+
correctly; this gap is specific to the plain `diffusers` PyTorch path.)
|
| 70 |
+
|
| 71 |
+
2. **Image conditioning gets destroyed into colorful static (critical).** This
|
| 72 |
+
checkpoint's scheduler ships `stochastic_sampling=True` (SDE sampling).
|
| 73 |
+
Cosmos3 anchors the conditioning frame by zeroing the model's predicted
|
| 74 |
+
velocity there — under a *deterministic* step that means "leave this frame
|
| 75 |
+
unchanged," but `FlowMatchEulerDiscreteScheduler`'s SDE branch computes
|
| 76 |
+
`x0 = sample - current_sigma * model_output` (= `sample`, since velocity is
|
| 77 |
+
0) then `prev_sample = (1 - next_sigma) * x0 + next_sigma * randn_tensor(...)`
|
| 78 |
+
— it re-noises by `next_sigma` **regardless of velocity**. Across this
|
| 79 |
+
checkpoint's 4 steps that compounds to ~99.6% fresh noise in the
|
| 80 |
+
conditioned frame: your input image comes out as colorful static while the
|
| 81 |
+
genuinely-denoised motion frames still look like plausible video (this
|
| 82 |
+
combination — garbage first frame, coherent-but-drifted rest — is exactly
|
| 83 |
+
how it presents). Disabling `stochastic_sampling` restores the correct
|
| 84 |
+
zero-velocity-is-a-no-op behavior. Confirmed by direct A/B render, same
|
| 85 |
+
seed/image/prompt, only this flag changed.
|
| 86 |
+
|
| 87 |
+
```python
|
| 88 |
+
def force_fixed_step_schedule(scheduler):
|
| 89 |
+
t_list = scheduler.config.fixed_step_sampler_config["t_list"]
|
| 90 |
+
orig = scheduler.set_timesteps
|
| 91 |
+
scheduler.set_timesteps = lambda num_inference_steps=None, device=None, **_: (
|
| 92 |
+
orig(sigmas=list(t_list), device=device)
|
| 93 |
+
)
|
| 94 |
+
if scheduler.config.stochastic_sampling:
|
| 95 |
+
scheduler.register_to_config(stochastic_sampling=False)
|
| 96 |
+
|
| 97 |
+
pipe = ... # Cosmos3OmniPipeline.from_pretrained(...)
|
| 98 |
+
force_fixed_step_schedule(pipe.scheduler)
|
| 99 |
+
|
| 100 |
+
result = pipe(prompt=..., image=..., guidance_scale=1.0, num_inference_steps=4, ...)
|
| 101 |
+
# guidance_scale=1.0 disables CFG; num_inference_steps is a no-op once patched
|
| 102 |
+
```
|
| 103 |
+
|
| 104 |
+
Verified against this exact repo: the patch produces a 4-iteration denoising
|
| 105 |
+
loop (not 35) with CFG off and a correctly-preserved conditioning frame
|
| 106 |
+
(not colorful static), matching the checkpoint's trained regime. The
|
| 107 |
+
save/restore round trip (`transformer/modelopt_state.pth`) reloads correctly
|
| 108 |
+
with 896 quantized weight wrappers active.
|
| 109 |
+
|
| 110 |
+
## Usage: Run Inference (single GPU, `diffusers`)
|
| 111 |
+
|
| 112 |
+
This repo is a `diffusers`-loadable repackage (`transformer/modelopt_state.pth`),
|
| 113 |
+
not NVIDIA's `vLLM-Omni` deployment export format. If you have a vLLM-Omni
|
| 114 |
+
cluster, use NVIDIA's original BF16 checkpoint and card instead. For everyone
|
| 115 |
+
else — anyone running this NVFP4 checkpoint on a single GPU — use the FastAPI
|
| 116 |
+
server included in this repo, which loads the checkpoint, applies the 4-step
|
| 117 |
+
scheduler fix above automatically, and exposes a plain HTTP endpoint.
|
| 118 |
+
|
| 119 |
+
### 1. Install
|
| 120 |
+
|
| 121 |
+
Requires a `diffusers` build with Cosmos3 support — not yet in a PyPI release
|
| 122 |
+
as of this writing, so install from the exact commit this checkpoint was
|
| 123 |
+
produced and validated against:
|
| 124 |
+
|
| 125 |
+
```bash
|
| 126 |
+
pip install "git+https://github.com/huggingface/diffusers.git@2c7efb95349296cf6bcce981ea036275a82a94df"
|
| 127 |
+
pip install nvidia-modelopt accelerate torch fastapi uvicorn python-multipart
|
| 128 |
+
```
|
| 129 |
+
|
| 130 |
+
### 2. Download this repo (weights + scripts together)
|
| 131 |
+
|
| 132 |
+
```bash
|
| 133 |
+
hf download prometheusAIR/Cosmos3-Super-Image2Video-4Step-NVFP4 \
|
| 134 |
+
--local-dir Cosmos3-Super-Image2Video-4Step-NVFP4
|
| 135 |
+
cd Cosmos3-Super-Image2Video-4Step-NVFP4
|
| 136 |
+
```
|
| 137 |
+
|
| 138 |
+
This pulls the whole ~39GB repo — NVFP4 weights, VAE, tokenizer, and the `.py`
|
| 139 |
+
scripts side by side, the same download either way.
|
| 140 |
+
|
| 141 |
+
### 3. Serve it
|
| 142 |
+
|
| 143 |
+
```bash
|
| 144 |
+
CUDA_VISIBLE_DEVICES=0 python serve_cosmos3_i2v4step_diffusers.py --repo .
|
| 145 |
+
```
|
| 146 |
+
|
| 147 |
+
One GPU with roughly 45GB+ free memory is enough — noticeably less than the
|
| 148 |
+
FP8 release (~70GB+), so this fits single 48GB-class cards (RTX 6000 Ada,
|
| 149 |
+
A6000, L40S) in addition to the larger ones (RTX PRO 6000, H100/H200,
|
| 150 |
+
A100-80GB). No multi-GPU sharding required. The server listens on
|
| 151 |
+
`http://localhost:8000` once it's done loading.
|
| 152 |
+
|
| 153 |
+
### 4. Use it
|
| 154 |
+
|
| 155 |
+
```bash
|
| 156 |
+
curl -s -X POST http://localhost:8000/animate \
|
| 157 |
+
-F image=@your_first_frame.png \
|
| 158 |
+
-F 'prompt=The robotic arm slowly lowers its gripper toward the objects and holds. Static camera.' \
|
| 159 |
+
-F num_frames=49 -F fps=24 \
|
| 160 |
+
--output clip.mp4
|
| 161 |
+
```
|
| 162 |
+
|
| 163 |
+
`num_frames` / `fps` / `height` / `width` are adjustable. `num_inference_steps`
|
| 164 |
+
and `guidance_scale` are intentionally not exposed — this checkpoint's 4-step,
|
| 165 |
+
CFG-free schedule is fixed and applied automatically by the server.
|
| 166 |
+
|
| 167 |
+
### Other scripts in this repo
|
| 168 |
+
|
| 169 |
+
- `quantize_cosmos3_i2v4step_streaming.py` — reproduces this NVFP4 quantization
|
| 170 |
+
(`--format nvfp4`) from NVIDIA's BF16 source checkpoint; also supports
|
| 171 |
+
`--format fp8` for the sibling release.
|
| 172 |
+
- `repackage_for_hf_i2v4step.py` — rebuilds this diffusers-loadable repo format
|
| 173 |
+
from a quantized transformer.
|
| 174 |
+
- `load_cosmos3_modelopt.py` — the underlying loader `serve_cosmos3_i2v4step_diffusers.py`
|
| 175 |
+
uses; import `load_pipe(...)` directly if you want a `pipe` object instead of
|
| 176 |
+
an HTTP server.
|
| 177 |
+
- `validate_cosmos3_i2v4step_fp8.py` — a minimal standalone image→video smoke
|
| 178 |
+
test; despite the filename (kept for consistency with the FP8 repo) it
|
| 179 |
+
takes `--format nvfp4|fp8` and works against either checkpoint.
|
| 180 |
+
|
| 181 |
+
## Responsible Use
|
| 182 |
+
|
| 183 |
+
See NVIDIA's [Bias](BIAS.md), [Explainability](EXPLAINABILITY.md),
|
| 184 |
+
[Safety & Security](SAFETY.md), and [Privacy](PRIVACY.md) subcards (included
|
| 185 |
+
in this repo), and the Limitations / Ethical Considerations sections of
|
| 186 |
+
[NVIDIA's original model card](https://huggingface.co/nvidia/Cosmos3-Super-Image2Video-4Step).
|
| 187 |
+
Report security vulnerabilities [here](https://www.nvidia.com/en-us/support/submit-security-vulnerability/).
|
SAFETY.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## Safety & Security
|
| 2 |
+
|
| 3 |
+
| Field | Response |
|
| 4 |
+
| :---- | :---- |
|
| 5 |
+
| Model Application(s) | World reasoning and generation for Physical AI. |
|
| 6 |
+
| Describe the life critical impact: | This model is not a safety-certified component and must not be used as the sole basis for life-critical decisions or control without additional system-level validation, safety analysis, and safeguards. The model is not designed or tested by NVIDIA for use in any system or application where the use of or failure of such system or application developed with the model could result in injury, death, or catastrophic damage. NVIDIA is not liable to any party, in whole or in part, for any claims or damages arising from those uses. Any system or application developed with the model must include sufficient safety and redundancy features and comply with applicable legal and regulatory standards and requirements. |
|
| 7 |
+
| Description of methods implemented in data acquisition or processing, if any, to address other types of potentially harmful data in the training, testing, and validation data: | Training, evaluation, and validation datasets pass through multi-stage automated and manual filtering to reduce harmful, unsafe, restricted, or policy-violating content. Pipelines include source-licensing review, deduplication, metadata-based and classifier-based moderation, embedding-based anomaly detection, and human audits on selected datasets. For Physical AI data (robotics, autonomous driving, industrial scenes), filtering also targets invalid action trajectories, physically implausible interactions, and unsafe control sequences. Synthetic and simulation-generated data are evaluated through internal validation before inclusion. Benchmark and red-team testing surface remaining safety gaps across world generation, reasoning, audio, and action tasks. No data-filtering process can guarantee complete removal; developers are responsible for application-specific safeguards and validation before deployment. |
|
| 8 |
+
| Description of any methods implemented in data acquisition or processing, if any, to address illegal or harmful content in the training data, including, but not limited to, child sexual abuse material (CSAM) and non-consensual intimate imagery (NCII) | In addition to the general unsafe-content filtering described above, training data acquisition and preprocessing apply CSAM- and NCII-specific safeguards: hash-matching systems against known CSAM databases, classifier-based moderation models trained specifically for explicit content and NCII detection, and provenance and licensing review for sources containing human imagery. Identified content is removed at ingest, with human review and targeted audits supplementing automated filtering for selected datasets. Despite these safeguards, no large-scale data-filtering system can guarantee complete detection. Ongoing monitoring and dataset review continue post-release. |
|
| 9 |
+
| Use Case Restrictions | Use is governed by the [OpenMDW1.1](https://openmdw.ai/) |
|
| 10 |
+
| Model and dataset restrictions | The Principle of least privilege (PoLP) is applied limiting access for dataset generation and model development. Restrictions enforce dataset access during training, and dataset license constraints adhered to. |
|
| 11 |
+
| Responsible Data Handling | This AI model was developed based on our policies to ensure responsible data handling and risk mitigation. The datasets used for training have been scanned for harmful content and illegal content, consistent with our policies including scanning for Child Sexual Abuse Material (CSAM). Ongoing review and monitoring mechanisms are in place based on our policies and to maintain data integrity. |
|
assets/example_first_frame.png
ADDED
|
Git LFS Details
|
assets/example_output.mp4
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:625d490237c02ed103797bc42b6c2aff9b219779b0de29226df7878c671ec907
|
| 3 |
+
size 8589231
|
assets/example_prompt.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"prompt": "{\"temporal_caption\": \"A fallen waffle cone lies on rough sunlit asphalt in an extreme low close-up, with a rounded scoop of vanilla and chocolate ice cream pressed against the road, a small melted puddle already spreading beneath it, and dry autumn leaves scattered around in warm late-afternoon light. The viewpoint stays near ground level and begins a slow, smooth arc around the cone from left to right, keeping the melting scoop dominant while the background street and leaves remain softly blurred. As the sun warms the ice cream, the glossy edges soften first, thin rivulets of vanilla and chocolate slide down the curved scoop, and the existing puddle widens into the cracks and pebbled texture of the asphalt. The waffle cone remains mostly rigid but grows slightly damp at the rim touching the ice cream, while the scoop loses its rounded shape, slumps lower, and exposes more of the cone’s open mouth. The moving viewpoint continues its gentle orbit, revealing the chocolate side thinning into streaks and the vanilla side collapsing into pale liquid that creeps outward under gravity. By the end, most of the ice cream has flattened into a shallow glossy stain that drains into small road fissures and spreads out of the immediate area, leaving the cone lying in place with only thin cream-colored and brown traces clinging to the asphalt in the warm light.\", \"duration\": \"7s\", \"fps\": 24.0, \"resolution\": {\"H\": 480, \"W\": 832}, \"aspect_ratio\": \"16,9\"}", "negative_prompt": "The video captures a series of frames showing macroblocking artifacts, chromatic aberration, high-frequency noise, and rolling shutter distortion. It includes static with no motion, motion blur, over-saturation, shaky footage, low resolution, grainy texture, pixelated images, poorly lit areas, underexposed and overexposed scenes, poor color balance, washed out colors, choppy sequences, jerky movements, low frame rate, bit-depth compression artifacts, color banding, unnatural transitions, outdated special effects, fake elements, unconvincing visuals, poorly edited content, jump cuts, hard cut, visual noise, and flickering. It features moiré patterns, edge halos, and temporal aliasing. Furthermore, the content defies common sense, generating illogical scenarios, nonsensical entities, absurd character behaviors, and conceptual paradoxes that violate basic human reasoning and everyday reality. The video looks like a surreal or glitchy hallucination. Overall, the video is of poor quality."}
|
assets/original_prompt.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
The ice cream melts and gradually disappears. The camera moves around.
|
chat_template.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"chat_template": "{%- if tools %}\n {{- '<|im_start|>system\\n' }}\n {%- if messages[0].role == 'system' %}\n {%- if messages[0].content is string %}\n {{- messages[0].content }}\n {%- else %}\n {%- for content in messages[0].content %}\n {%- if 'text' in content %}\n {{- content.text }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {{- '\\n\\n' }}\n {%- endif %}\n {{- \"# Tools\\n\\nYou may call one or more functions to assist with the user query.\\n\\nYou are provided with function signatures within <tools></tools> XML tags:\\n<tools>\" }}\n {%- for tool in tools %}\n {{- \"\\n\" }}\n {{- tool | tojson }}\n {%- endfor %}\n {{- \"\\n</tools>\\n\\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\\n<tool_call>\\n{\\\"name\\\": <function-name>, \\\"arguments\\\": <args-json-object>}\\n</tool_call><|im_end|>\\n\" }}\n{%- else %}\n {%- if messages[0].role == 'system' %}\n {{- '<|im_start|>system\\n' }}\n {%- if messages[0].content is string %}\n {{- messages[0].content }}\n {%- else %}\n {%- for content in messages[0].content %}\n {%- if 'text' in content %}\n {{- content.text }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {{- '<|im_end|>\\n' }}\n {%- endif %}\n{%- endif %}\n{%- set image_count = namespace(value=0) %}\n{%- set video_count = namespace(value=0) %}\n{%- for message in messages %}\n {%- if message.role == \"user\" %}\n {{- '<|im_start|>' + message.role + '\\n' }}\n {%- if message.content is string %}\n {{- message.content }}\n {%- else %}\n {%- for content in message.content %}\n {%- if content.type == 'image' or 'image' in content or 'image_url' in content %}\n {%- set image_count.value = image_count.value + 1 %}\n {%- if add_vision_id %}Picture {{ image_count.value }}: {% endif -%}\n <|vision_start|><|image_pad|><|vision_end|>\n {%- elif content.type == 'video' or 'video' in content %}\n {%- set video_count.value = video_count.value + 1 %}\n {%- if add_vision_id %}Video {{ video_count.value }}: {% endif -%}\n <|vision_start|><|video_pad|><|vision_end|>\n {%- elif 'text' in content %}\n {{- content.text }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {{- '<|im_end|>\\n' }}\n {%- elif message.role == \"assistant\" %}\n {{- '<|im_start|>' + message.role + '\\n' }}\n {%- if message.content is string %}\n {{- message.content }}\n {%- else %}\n {%- for content_item in message.content %}\n {%- if 'text' in content_item %}\n {{- content_item.text }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {%- if message.tool_calls %}\n {%- for tool_call in message.tool_calls %}\n {%- if (loop.first and message.content) or (not loop.first) %}\n {{- '\\n' }}\n {%- endif %}\n {%- if tool_call.function %}\n {%- set tool_call = tool_call.function %}\n {%- endif %}\n {{- '<tool_call>\\n{\"name\": \"' }}\n {{- tool_call.name }}\n {{- '\", \"arguments\": ' }}\n {%- if tool_call.arguments is string %}\n {{- tool_call.arguments }}\n {%- else %}\n {{- tool_call.arguments | tojson }}\n {%- endif %}\n {{- '}\\n</tool_call>' }}\n {%- endfor %}\n {%- endif %}\n {{- '<|im_end|>\\n' }}\n {%- elif message.role == \"tool\" %}\n {%- if loop.first or (messages[loop.index0 - 1].role != \"tool\") %}\n {{- '<|im_start|>user' }}\n {%- endif %}\n {{- '\\n<tool_response>\\n' }}\n {%- if message.content is string %}\n {{- message.content }}\n {%- else %}\n {%- for content in message.content %}\n {%- if content.type == 'image' or 'image' in content or 'image_url' in content %}\n {%- set image_count.value = image_count.value + 1 %}\n {%- if add_vision_id %}Picture {{ image_count.value }}: {% endif -%}\n <|vision_start|><|image_pad|><|vision_end|>\n {%- elif content.type == 'video' or 'video' in content %}\n {%- set video_count.value = video_count.value + 1 %}\n {%- if add_vision_id %}Video {{ video_count.value }}: {% endif -%}\n <|vision_start|><|video_pad|><|vision_end|>\n {%- elif 'text' in content %}\n {{- content.text }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {{- '\\n</tool_response>' }}\n {%- if loop.last or (messages[loop.index0 + 1].role != \"tool\") %}\n {{- '<|im_end|>\\n' }}\n {%- endif %}\n {%- endif %}\n{%- endfor %}\n{%- if add_generation_prompt %}\n {{- '<|im_start|>assistant\\n' }}\n{%- endif %}\n"
|
| 3 |
+
}
|
checkpoint.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"checkpoint_type": "hf",
|
| 3 |
+
"source_weights": "ema",
|
| 4 |
+
"student_only": true
|
| 5 |
+
}
|
config.json
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"allow_patterns_overrides": [
|
| 3 |
+
"*/*.safetensors"
|
| 4 |
+
],
|
| 5 |
+
"architectures": [
|
| 6 |
+
"Cosmos3ForConditionalGeneration"
|
| 7 |
+
],
|
| 8 |
+
"image_token_id": 151655,
|
| 9 |
+
"model": {
|
| 10 |
+
"_recursive_": false,
|
| 11 |
+
"_target": "omni_mot_model",
|
| 12 |
+
"config": {
|
| 13 |
+
"_type": "omni_mot_model_config",
|
| 14 |
+
"action_gen": false,
|
| 15 |
+
"activation_checkpointing": {
|
| 16 |
+
"_type": "activation_checkpointing_config",
|
| 17 |
+
"determinism_check": "default",
|
| 18 |
+
"mode": "full",
|
| 19 |
+
"preserve_rng_state": true,
|
| 20 |
+
"save_ops_regex": [
|
| 21 |
+
"fmha"
|
| 22 |
+
]
|
| 23 |
+
},
|
| 24 |
+
"causal_training_strategy": "none",
|
| 25 |
+
"compile": {
|
| 26 |
+
"_type": "compile_config",
|
| 27 |
+
"compile_dynamic": true,
|
| 28 |
+
"compiled_region": "language",
|
| 29 |
+
"coordinate_descent_tuning": false,
|
| 30 |
+
"enabled": false,
|
| 31 |
+
"max_autotune_pointwise": false,
|
| 32 |
+
"use_cuda_graphs": false
|
| 33 |
+
},
|
| 34 |
+
"diffusion_expert_config": {
|
| 35 |
+
"_type": "diffusion_expert_config",
|
| 36 |
+
"base_fps": 16,
|
| 37 |
+
"enable_fps_modulation": true,
|
| 38 |
+
"load_weights_from_pretrained": true,
|
| 39 |
+
"max_vae_latent_side_after_patchify": 20,
|
| 40 |
+
"patch_spatial": 2,
|
| 41 |
+
"sound_base_temporal_compression_factor": null,
|
| 42 |
+
"timestep_range": 1.0,
|
| 43 |
+
"unified_3d_mrope_reset_spatial_ids": true,
|
| 44 |
+
"unified_3d_mrope_temporal_modality_margin": 15000,
|
| 45 |
+
"vision_temporal_position_mode": "latent_index"
|
| 46 |
+
},
|
| 47 |
+
"ema": {
|
| 48 |
+
"_type": "ema_config",
|
| 49 |
+
"enabled": false,
|
| 50 |
+
"iteration_shift": 0,
|
| 51 |
+
"rate": 0.1
|
| 52 |
+
},
|
| 53 |
+
"enable_input_bias": true,
|
| 54 |
+
"exclude_reasoner_weights_from_checkpoint": false,
|
| 55 |
+
"fixed_step_sampler_config": {
|
| 56 |
+
"_type": "fixed_step_sampler_config",
|
| 57 |
+
"sample_type": "sde",
|
| 58 |
+
"t_list": [
|
| 59 |
+
1.0,
|
| 60 |
+
0.9375,
|
| 61 |
+
0.8333333333333334,
|
| 62 |
+
0.625
|
| 63 |
+
]
|
| 64 |
+
},
|
| 65 |
+
"input_caption_key": "ai_caption",
|
| 66 |
+
"input_image_key": "images",
|
| 67 |
+
"input_video_key": "video",
|
| 68 |
+
"joint_attn_implementation": "two_way",
|
| 69 |
+
"latent_downsample_factor": 16,
|
| 70 |
+
"lbl": {
|
| 71 |
+
"_type": "lbl_config",
|
| 72 |
+
"coeff_gen": null,
|
| 73 |
+
"coeff_und": null,
|
| 74 |
+
"method": "local"
|
| 75 |
+
},
|
| 76 |
+
"log_enc_time_every_n": 100,
|
| 77 |
+
"lora_alpha": 32,
|
| 78 |
+
"lora_enabled": false,
|
| 79 |
+
"lora_rank": 16,
|
| 80 |
+
"lora_target_modules": "q_proj_moe_gen,k_proj_moe_gen,v_proj_moe_gen,o_proj_moe_gen",
|
| 81 |
+
"max_action_dim": 32,
|
| 82 |
+
"max_num_tokens_after_packing": 45056,
|
| 83 |
+
"natten_parameter_list": null,
|
| 84 |
+
"net": null,
|
| 85 |
+
"num_embodiment_domains": 32,
|
| 86 |
+
"parallelism": {
|
| 87 |
+
"_type": "parallelism_config",
|
| 88 |
+
"attention_io_layout": "sequence_sharded",
|
| 89 |
+
"cfg_parallel_shard_degree": 1,
|
| 90 |
+
"context_parallel_shard_degree": 1,
|
| 91 |
+
"data_parallel_replicate_degree": 1,
|
| 92 |
+
"data_parallel_shard_degree": 128,
|
| 93 |
+
"enable_inference_mode": false,
|
| 94 |
+
"fsdp_master_dtype": "float32"
|
| 95 |
+
},
|
| 96 |
+
"precision": "bfloat16",
|
| 97 |
+
"rectified_flow_inference_config": {
|
| 98 |
+
"_type": "rectified_flow_inference_config",
|
| 99 |
+
"num_train_timesteps": 1000,
|
| 100 |
+
"scheduler_type": "unipc",
|
| 101 |
+
"shift": 1,
|
| 102 |
+
"use_dynamic_shifting": false
|
| 103 |
+
},
|
| 104 |
+
"rectified_flow_training_config": {
|
| 105 |
+
"_type": "rectified_flow_training_config",
|
| 106 |
+
"action_loss_weight": 10.0,
|
| 107 |
+
"image_loss_scale": null,
|
| 108 |
+
"independent_action_schedule": false,
|
| 109 |
+
"independent_sound_schedule": false,
|
| 110 |
+
"loss_scale": 10.0,
|
| 111 |
+
"normalize_loss_by_active": false,
|
| 112 |
+
"shift": {
|
| 113 |
+
"256": 3,
|
| 114 |
+
"480": 5,
|
| 115 |
+
"720": 10
|
| 116 |
+
},
|
| 117 |
+
"shift_action": null,
|
| 118 |
+
"shift_sound": null,
|
| 119 |
+
"sound_loss_scale": null,
|
| 120 |
+
"train_time_action_distribution": "logitnormal",
|
| 121 |
+
"train_time_image_distribution": "logitnormal",
|
| 122 |
+
"train_time_sound_distribution": "logitnormal",
|
| 123 |
+
"train_time_video_distribution": "uniform",
|
| 124 |
+
"train_time_weight": "uniform",
|
| 125 |
+
"use_discrete_rf": false,
|
| 126 |
+
"use_dynamic_shift": false
|
| 127 |
+
},
|
| 128 |
+
"resolution": "480",
|
| 129 |
+
"sound_dim": null,
|
| 130 |
+
"sound_gen": false,
|
| 131 |
+
"sound_latent_fps": 25,
|
| 132 |
+
"sound_tokenizer": null,
|
| 133 |
+
"state_ch": 48,
|
| 134 |
+
"state_t": 300,
|
| 135 |
+
"tokenizer": {
|
| 136 |
+
"_target": "wan2pt2_vae_interface",
|
| 137 |
+
"bucket_name": "bucket",
|
| 138 |
+
"causal": true,
|
| 139 |
+
"chunk_duration": 93,
|
| 140 |
+
"encode_bucket_multiple": 1,
|
| 141 |
+
"encode_chunk_frames": {
|
| 142 |
+
"256": 68,
|
| 143 |
+
"480": 24,
|
| 144 |
+
"720": 12
|
| 145 |
+
},
|
| 146 |
+
"encode_exact_durations": [
|
| 147 |
+
17,
|
| 148 |
+
61,
|
| 149 |
+
73
|
| 150 |
+
],
|
| 151 |
+
"keep_decoder_cache": false,
|
| 152 |
+
"object_store_credential_path_pretrained": "",
|
| 153 |
+
"spatial_compression_factor": 16,
|
| 154 |
+
"temporal_compression_factor": 4,
|
| 155 |
+
"temporal_window": null,
|
| 156 |
+
"use_streaming_encode": false,
|
| 157 |
+
"vae_path": "pretrained/tokenizers/video/wan2pt2/Wan2.2_VAE.pth"
|
| 158 |
+
},
|
| 159 |
+
"video_temporal_causal": false,
|
| 160 |
+
"vision_gen": true,
|
| 161 |
+
"vlm_config": {
|
| 162 |
+
"_type": "vlm_config",
|
| 163 |
+
"layer_module": null,
|
| 164 |
+
"model_instance": {
|
| 165 |
+
"_target": "qwen3_vl_text_for_causal_lm",
|
| 166 |
+
"config": {
|
| 167 |
+
"_target": "create_vlm_config",
|
| 168 |
+
"base_config": {
|
| 169 |
+
"_target": "qwen3_vl_mot_config_from_json_file",
|
| 170 |
+
"json_file": "cosmos3://vfm/models/vlm/qwen3_vl/configs/Qwen3-VL-32B-Instruct.json"
|
| 171 |
+
},
|
| 172 |
+
"qk_norm_for_text": true
|
| 173 |
+
}
|
| 174 |
+
},
|
| 175 |
+
"model_name": "nvidia/Cosmos3-Super-Reasoner",
|
| 176 |
+
"pretrained_weights": {
|
| 177 |
+
"_type": "pretrained_weights_config",
|
| 178 |
+
"backbone_path": "",
|
| 179 |
+
"checkpoint_format": null,
|
| 180 |
+
"credentials_path": "",
|
| 181 |
+
"enable_gcs_patch_in_boto3": false,
|
| 182 |
+
"enabled": false
|
| 183 |
+
},
|
| 184 |
+
"qk_norm": false,
|
| 185 |
+
"safetensors_path": "",
|
| 186 |
+
"tie_word_embeddings": false,
|
| 187 |
+
"tokenizer": {
|
| 188 |
+
"_target": "create_qwen2_tokenizer_with_download",
|
| 189 |
+
"config_variant": "hf",
|
| 190 |
+
"pretrained_model_name": "Qwen/Qwen3-VL-32B-Instruct"
|
| 191 |
+
},
|
| 192 |
+
"use_system_prompt": false
|
| 193 |
+
}
|
| 194 |
+
}
|
| 195 |
+
},
|
| 196 |
+
"model_type": "cosmos3_omni",
|
| 197 |
+
"text_config": {
|
| 198 |
+
"attention_bias": false,
|
| 199 |
+
"attention_dropout": 0.0,
|
| 200 |
+
"bos_token_id": 151643,
|
| 201 |
+
"dtype": "bfloat16",
|
| 202 |
+
"eos_token_id": 151645,
|
| 203 |
+
"head_dim": 128,
|
| 204 |
+
"hidden_act": "silu",
|
| 205 |
+
"hidden_size": 5120,
|
| 206 |
+
"initializer_range": 0.02,
|
| 207 |
+
"intermediate_size": 25600,
|
| 208 |
+
"max_position_embeddings": 262144,
|
| 209 |
+
"model_type": "qwen3_vl_text",
|
| 210 |
+
"num_attention_heads": 64,
|
| 211 |
+
"num_hidden_layers": 64,
|
| 212 |
+
"num_key_value_heads": 8,
|
| 213 |
+
"rms_norm_eps": 1e-06,
|
| 214 |
+
"rope_scaling": {
|
| 215 |
+
"mrope_interleaved": true,
|
| 216 |
+
"mrope_section": [
|
| 217 |
+
24,
|
| 218 |
+
20,
|
| 219 |
+
20
|
| 220 |
+
],
|
| 221 |
+
"rope_type": "default"
|
| 222 |
+
},
|
| 223 |
+
"rope_theta": 5000000,
|
| 224 |
+
"use_cache": true,
|
| 225 |
+
"vocab_size": 151936
|
| 226 |
+
},
|
| 227 |
+
"tie_word_embeddings": false,
|
| 228 |
+
"transformers_version": "4.57.0.dev0",
|
| 229 |
+
"video_token_id": 151656,
|
| 230 |
+
"vision_config": {
|
| 231 |
+
"deepstack_visual_indexes": [
|
| 232 |
+
8,
|
| 233 |
+
16,
|
| 234 |
+
24
|
| 235 |
+
],
|
| 236 |
+
"depth": 27,
|
| 237 |
+
"hidden_act": "gelu_pytorch_tanh",
|
| 238 |
+
"hidden_size": 1152,
|
| 239 |
+
"in_channels": 3,
|
| 240 |
+
"initializer_range": 0.02,
|
| 241 |
+
"intermediate_size": 4304,
|
| 242 |
+
"model_type": "qwen3_vl",
|
| 243 |
+
"num_heads": 16,
|
| 244 |
+
"num_position_embeddings": 2304,
|
| 245 |
+
"out_hidden_size": 5120,
|
| 246 |
+
"patch_size": 16,
|
| 247 |
+
"spatial_merge_size": 2,
|
| 248 |
+
"temporal_patch_size": 2
|
| 249 |
+
},
|
| 250 |
+
"vision_end_token_id": 151653,
|
| 251 |
+
"vision_start_token_id": 151652
|
| 252 |
+
}
|
generation_config.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bos_token_id": 151643,
|
| 3 |
+
"pad_token_id": 151643,
|
| 4 |
+
"do_sample": true,
|
| 5 |
+
"eos_token_id": [
|
| 6 |
+
151645,
|
| 7 |
+
151643
|
| 8 |
+
],
|
| 9 |
+
"top_p": 0.8,
|
| 10 |
+
"top_k": 20,
|
| 11 |
+
"temperature": 0.7,
|
| 12 |
+
"repetition_penalty": 1.0,
|
| 13 |
+
"transformers_version": "4.56.0"
|
| 14 |
+
}
|
images/aa-i2v-all-models-2026-07-17.png
ADDED
|
Git LFS Details
|
images/aa-i2v-open-models-2026-07-17.png
ADDED
|
Git LFS Details
|
load_cosmos3_modelopt.py
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""
|
| 3 |
+
Drop-in loader for the weight-only NVFP4 / FP8 (NVIDIA ModelOpt) Cosmos3-Super checkpoint
|
| 4 |
+
saved in the ROUND-TRIPPABLE format (modelopt_state.pth present -- see repackage_for_hf.py).
|
| 5 |
+
|
| 6 |
+
Current diffusers + accelerate + modelopt treat this path as experimental; each shim below
|
| 7 |
+
works around a specific, source-verified version-skew gap. None modify the checkpoint:
|
| 8 |
+
|
| 9 |
+
1. enable_huggingface_checkpointing()
|
| 10 |
+
Registers ModelOpt's HF handlers so `from_pretrained` restores the quantized module
|
| 11 |
+
structure from modelopt_state.pth before weights load.
|
| 12 |
+
|
| 13 |
+
2. set_module_tensor_to_device patch (parameter materialization)
|
| 14 |
+
The modelopt_state restore runs inside diffusers' meta-device init, so each quantized
|
| 15 |
+
weight is a QTensorWrapper whose storage is a META tensor carrying dequant metadata.
|
| 16 |
+
`param.data = real` can't cross meta<->real, and accelerate's rebuild both rejects
|
| 17 |
+
requires_grad and discards metadata. We REPLACE the parameter with a fresh wrapper
|
| 18 |
+
around the loaded bytes + the existing metadata. Two extra duties here:
|
| 19 |
+
- payload dtype restore: diffusers casts floating params to torch_dtype during load
|
| 20 |
+
when no hf_quantizer is present (model_loading_utils.py -- their own TODO flags
|
| 21 |
+
float8). FP8 payloads are floating and arrive cast to bf16; we cast back to the
|
| 22 |
+
wrapper's payload dtype (exact: every e4m3fn value round-trips through bf16).
|
| 23 |
+
NVFP4's uint8 payload is never cast, so this is a no-op there.
|
| 24 |
+
- direct-to-GPU materialization: staging payloads on CPU would put the whole packed
|
| 25 |
+
model in system RAM (FP8: ~64 GB on a 32 GB box -> OOM-killed; NVFP4 only survived
|
| 26 |
+
because uncast tensors stay mmap-backed). Wrappers go straight to `materialize_device`.
|
| 27 |
+
|
| 28 |
+
3. Post-restore quantizer re-disable
|
| 29 |
+
modelopt_state replays the QUANT CONFIG, not imperative `.disable()` calls made after
|
| 30 |
+
quantize. The NVFP4 build used NVFP4_DEFAULT_CFG (activation quantization ON in-config)
|
| 31 |
+
with activations disabled imperatively -- so the restored model comes back with ~1806
|
| 32 |
+
dynamic fake-quant activation quantizers active: ~10x slower, fatter, and quantizing
|
| 33 |
+
activations the validated regime never quantized. We re-apply weight-only + spare
|
| 34 |
+
disabling after load. (FP8's config had the disables baked in; this is then a no-op.)
|
| 35 |
+
|
| 36 |
+
4. Full bf16 normalization (the validated serve regime)
|
| 37 |
+
Cosmos3OmniTransformer pins time_embedder to fp32 via _keep_in_fp32_modules
|
| 38 |
+
(transformer_cosmos3.py:297); the quantized model runs all-bf16. Cast floating buffers
|
| 39 |
+
and non-wrapper floating params to bf16, retarget wrapper dequant dtype to bf16, and
|
| 40 |
+
register bf16 input-cast pre-hooks on the time embedders.
|
| 41 |
+
|
| 42 |
+
5. NVIDIAModelOptQuantizer.create_quantized_param patch
|
| 43 |
+
Only relevant if a checkpoint carries an embedded quantization_config (hf_quantizer
|
| 44 |
+
path): requires_grad only for float/complex tensors. Kept for robustness.
|
| 45 |
+
|
| 46 |
+
Usage (library):
|
| 47 |
+
from load_cosmos3_modelopt import load_pipe
|
| 48 |
+
pipe = load_pipe("YOUR_HF_USERNAME/Cosmos3-Super-nvfp4") # or a local dir
|
| 49 |
+
# NOTE: a bare pipe(prompt) call renders the pipeline DEFAULT: a 189-frame 720x1280
|
| 50 |
+
# video (~8 s at 24 fps) -- not a still. For a single-image smoke test, be explicit:
|
| 51 |
+
r = pipe("a red cube on a table", height=1024, width=1024, num_frames=1,
|
| 52 |
+
num_inference_steps=50, guidance_scale=4.0)
|
| 53 |
+
r.video[0].save("out.png") # .video is the list of PIL frames; [0] is the image
|
| 54 |
+
|
| 55 |
+
Usage (interactive -- lands in a REPL with `pipe` loaded):
|
| 56 |
+
CUDA_VISIBLE_DEVICES=0 python -i load_cosmos3_modelopt.py ./cosmos3-super-nvfp4-hf
|
| 57 |
+
"""
|
| 58 |
+
import os
|
| 59 |
+
|
| 60 |
+
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
|
| 61 |
+
|
| 62 |
+
import torch
|
| 63 |
+
|
| 64 |
+
SPARE_SUBSTRINGS = [
|
| 65 |
+
"time_embedder", "proj_in", "proj_out", "lm_head", "embed", "norm", "audio_proj",
|
| 66 |
+
]
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def _qtensor_wrapper_cls():
|
| 70 |
+
try:
|
| 71 |
+
from modelopt.torch.quantization.qtensor.base_qtensor import QTensorWrapper
|
| 72 |
+
return QTensorWrapper
|
| 73 |
+
except Exception:
|
| 74 |
+
return None
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def _patch_modelopt_quantizer() -> None:
|
| 78 |
+
"""diffusers pre-quantized hf_quantizer branch: only float/complex tensors may require grad."""
|
| 79 |
+
import diffusers.quantizers.modelopt.modelopt_quantizer as moq
|
| 80 |
+
|
| 81 |
+
if getattr(moq.NVIDIAModelOptQuantizer, "_cqp_patched", False):
|
| 82 |
+
return
|
| 83 |
+
_orig = moq.NVIDIAModelOptQuantizer.create_quantized_param
|
| 84 |
+
|
| 85 |
+
def _cqp(self, model, param_value, param_name, target_device, *args, **kwargs):
|
| 86 |
+
if self.pre_quantized:
|
| 87 |
+
module, tname = moq.get_module_from_name(model, param_name)
|
| 88 |
+
needs_grad = param_value.is_floating_point() or param_value.is_complex()
|
| 89 |
+
module._parameters[tname] = torch.nn.Parameter(
|
| 90 |
+
param_value.to(device=target_device), requires_grad=needs_grad
|
| 91 |
+
)
|
| 92 |
+
return
|
| 93 |
+
return _orig(self, model, param_value, param_name, target_device, *args, **kwargs)
|
| 94 |
+
|
| 95 |
+
moq.NVIDIAModelOptQuantizer.create_quantized_param = _cqp
|
| 96 |
+
moq.NVIDIAModelOptQuantizer._cqp_patched = True
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def _patch_qtensor_loading() -> None:
|
| 100 |
+
"""Materialize restored (meta) QTensorWrapper params: replace the parameter object with
|
| 101 |
+
a fresh wrapper around the loaded bytes, restoring the payload dtype (undoes diffusers'
|
| 102 |
+
float cast on FP8) and landing directly on the target device (keeps payloads out of RAM)."""
|
| 103 |
+
import diffusers.models.model_loading_utils as mlu
|
| 104 |
+
|
| 105 |
+
if getattr(mlu, "_qtw_inplace_patched", False):
|
| 106 |
+
return
|
| 107 |
+
QTensorWrapper = _qtensor_wrapper_cls()
|
| 108 |
+
if QTensorWrapper is None:
|
| 109 |
+
return # different modelopt layout; nothing to patch
|
| 110 |
+
|
| 111 |
+
_orig = mlu.set_module_tensor_to_device
|
| 112 |
+
stats = {"materialized": 0, "target_device": None}
|
| 113 |
+
|
| 114 |
+
def _patched(model, tensor_name, device, value=None, *args, **kwargs):
|
| 115 |
+
if value is not None:
|
| 116 |
+
module, leaf = model, tensor_name
|
| 117 |
+
if "." in tensor_name:
|
| 118 |
+
mod_path, leaf = tensor_name.rsplit(".", 1)
|
| 119 |
+
try:
|
| 120 |
+
module = model.get_submodule(mod_path)
|
| 121 |
+
except AttributeError:
|
| 122 |
+
module = None
|
| 123 |
+
if module is not None:
|
| 124 |
+
cur = getattr(module, "_parameters", {}).get(leaf)
|
| 125 |
+
if isinstance(cur, QTensorWrapper):
|
| 126 |
+
tgt = stats.get("target_device") or device
|
| 127 |
+
module._parameters[leaf] = QTensorWrapper(
|
| 128 |
+
value.to(device=tgt, dtype=cur.data.dtype), # exact cast-back for fp8
|
| 129 |
+
metadata=dict(cur.metadata),
|
| 130 |
+
)
|
| 131 |
+
stats["materialized"] += 1
|
| 132 |
+
return None
|
| 133 |
+
return _orig(model, tensor_name, device, value=value, *args, **kwargs)
|
| 134 |
+
|
| 135 |
+
mlu.set_module_tensor_to_device = _patched
|
| 136 |
+
mlu._qtw_inplace_patched = True
|
| 137 |
+
mlu._qtw_stats = stats
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
def _enforce_weight_only(transformer) -> None:
|
| 141 |
+
"""Re-apply the validated weight-only + spare regime: the state replay re-enables any
|
| 142 |
+
quantizers that were disabled imperatively after quantize (NVFP4 default cfg has
|
| 143 |
+
activation quantization ON in-config)."""
|
| 144 |
+
n_act = n_spare = 0
|
| 145 |
+
for name, m in transformer.named_modules():
|
| 146 |
+
if not (name.endswith("_quantizer") and hasattr(m, "disable")):
|
| 147 |
+
continue
|
| 148 |
+
if name.endswith("weight_quantizer"):
|
| 149 |
+
if any(s in name for s in SPARE_SUBSTRINGS):
|
| 150 |
+
if getattr(m, "is_enabled", False):
|
| 151 |
+
n_spare += 1
|
| 152 |
+
m.disable()
|
| 153 |
+
else:
|
| 154 |
+
if getattr(m, "is_enabled", False):
|
| 155 |
+
n_act += 1
|
| 156 |
+
m.disable()
|
| 157 |
+
print(f"[load] re-disabled quantizers the state replay re-enabled: "
|
| 158 |
+
f"{n_act} activation, {n_spare} spare-weight")
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
def _apply_dtype_nudges(transformer) -> None:
|
| 162 |
+
"""Reproduce the validated all-bf16 serve regime (all no-ops where already aligned)."""
|
| 163 |
+
QTensorWrapper = _qtensor_wrapper_cls() or ()
|
| 164 |
+
|
| 165 |
+
n_buf = n_par = n_meta = 0
|
| 166 |
+
for m in transformer.modules():
|
| 167 |
+
for bn, buf in list(m._buffers.items()):
|
| 168 |
+
if buf is not None and buf.is_floating_point() and buf.dtype != torch.bfloat16:
|
| 169 |
+
m._buffers[bn] = buf.to(torch.bfloat16)
|
| 170 |
+
n_buf += 1
|
| 171 |
+
for _, p in transformer.named_parameters():
|
| 172 |
+
if isinstance(p, QTensorWrapper):
|
| 173 |
+
d = p.metadata.get("dtype")
|
| 174 |
+
if isinstance(d, torch.dtype) and d.is_floating_point and d != torch.bfloat16:
|
| 175 |
+
p.metadata["dtype"] = torch.bfloat16 # dequant target only; payload untouched
|
| 176 |
+
n_meta += 1
|
| 177 |
+
continue # packed payloads: never cast
|
| 178 |
+
if p.is_floating_point() and p.dtype != torch.bfloat16:
|
| 179 |
+
p.data = p.data.to(torch.bfloat16)
|
| 180 |
+
n_par += 1
|
| 181 |
+
print(f"[load] normalized to bf16: {n_par} params, {n_buf} buffers; "
|
| 182 |
+
f"retargeted {n_meta} dequant dtypes")
|
| 183 |
+
|
| 184 |
+
def _cast_bf16(_m, args):
|
| 185 |
+
return tuple(
|
| 186 |
+
a.to(torch.bfloat16)
|
| 187 |
+
if torch.is_tensor(a) and a.is_floating_point() and a.dtype != torch.bfloat16
|
| 188 |
+
else a
|
| 189 |
+
for a in args
|
| 190 |
+
)
|
| 191 |
+
|
| 192 |
+
for name, m in transformer.named_modules():
|
| 193 |
+
if "time_embedder" in name and hasattr(m, "linear_1"):
|
| 194 |
+
m.register_forward_pre_hook(_cast_bf16)
|
| 195 |
+
|
| 196 |
+
|
| 197 |
+
def load_pipe(
|
| 198 |
+
model_id_or_path: str,
|
| 199 |
+
*,
|
| 200 |
+
torch_dtype=torch.bfloat16,
|
| 201 |
+
enable_safety_checker: bool = False,
|
| 202 |
+
device: str = "cuda",
|
| 203 |
+
materialize_device: str | None = "cuda", # packed weights stream straight here (RAM stays low)
|
| 204 |
+
**kwargs,
|
| 205 |
+
):
|
| 206 |
+
"""Load a ModelOpt-quantized Cosmos3-Super pipeline with all load-time fixes applied."""
|
| 207 |
+
from diffusers import Cosmos3OmniPipeline
|
| 208 |
+
from modelopt.torch.opt import enable_huggingface_checkpointing
|
| 209 |
+
|
| 210 |
+
enable_huggingface_checkpointing() # must run before from_pretrained
|
| 211 |
+
_patch_modelopt_quantizer()
|
| 212 |
+
_patch_qtensor_loading()
|
| 213 |
+
|
| 214 |
+
import diffusers.models.model_loading_utils as mlu
|
| 215 |
+
if hasattr(mlu, "_qtw_stats"):
|
| 216 |
+
mlu._qtw_stats["materialized"] = 0
|
| 217 |
+
mlu._qtw_stats["target_device"] = materialize_device
|
| 218 |
+
|
| 219 |
+
pipe = Cosmos3OmniPipeline.from_pretrained(
|
| 220 |
+
model_id_or_path,
|
| 221 |
+
torch_dtype=torch_dtype,
|
| 222 |
+
enable_safety_checker=enable_safety_checker,
|
| 223 |
+
**kwargs,
|
| 224 |
+
)
|
| 225 |
+
|
| 226 |
+
n_mat = getattr(mlu, "_qtw_stats", {}).get("materialized", 0)
|
| 227 |
+
print(f"[load] materialized {n_mat} packed quantized weight tensors")
|
| 228 |
+
|
| 229 |
+
transformer = getattr(pipe, "transformer", None)
|
| 230 |
+
if transformer is not None:
|
| 231 |
+
_enforce_weight_only(transformer)
|
| 232 |
+
_apply_dtype_nudges(transformer)
|
| 233 |
+
|
| 234 |
+
pipe = pipe.to(device)
|
| 235 |
+
|
| 236 |
+
QTensorWrapper = _qtensor_wrapper_cls()
|
| 237 |
+
if QTensorWrapper is not None and transformer is not None:
|
| 238 |
+
n_live = sum(1 for p in transformer.parameters() if isinstance(p, QTensorWrapper))
|
| 239 |
+
print(f"[load] {n_live} quantized weight wrappers active after move to {device}")
|
| 240 |
+
if n_mat and not n_live:
|
| 241 |
+
print("[load] WARNING: wrappers were lost during .to() -- do not render; report this")
|
| 242 |
+
|
| 243 |
+
return pipe
|
| 244 |
+
|
| 245 |
+
|
| 246 |
+
if __name__ == "__main__":
|
| 247 |
+
import sys
|
| 248 |
+
|
| 249 |
+
path = sys.argv[1] if len(sys.argv) > 1 else "./cosmos3-super-nvfp4-hf"
|
| 250 |
+
print(f"[load] loading {path} ...")
|
| 251 |
+
pipe = load_pipe(path)
|
| 252 |
+
print("[load] OK -- `pipe` is ready.")
|
| 253 |
+
print(" NOTE: bare pipe(prompt) renders a 189-frame 720x1280 video (pipeline default).")
|
| 254 |
+
print(" single-still smoke test:")
|
| 255 |
+
print(" r = pipe('a red cube on a table', height=1024, width=1024, num_frames=1,")
|
| 256 |
+
print(" num_inference_steps=50, guidance_scale=4.0); r.video[0].save('out.png')")
|
merges.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
model.safetensors.index.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
model_index.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_class_name": "Cosmos3OmniPipeline",
|
| 3 |
+
"_diffusers_version": "0.39.0",
|
| 4 |
+
"safety_checker": [
|
| 5 |
+
null,
|
| 6 |
+
null
|
| 7 |
+
],
|
| 8 |
+
"scheduler": [
|
| 9 |
+
"diffusers",
|
| 10 |
+
"FlowMatchEulerDiscreteScheduler"
|
| 11 |
+
],
|
| 12 |
+
"sound_tokenizer": [
|
| 13 |
+
null,
|
| 14 |
+
null
|
| 15 |
+
],
|
| 16 |
+
"text_tokenizer": [
|
| 17 |
+
"transformers",
|
| 18 |
+
"Qwen2TokenizerFast"
|
| 19 |
+
],
|
| 20 |
+
"transformer": [
|
| 21 |
+
"diffusers",
|
| 22 |
+
"Cosmos3OmniTransformer"
|
| 23 |
+
],
|
| 24 |
+
"vae": [
|
| 25 |
+
"diffusers",
|
| 26 |
+
"AutoencoderKLWan"
|
| 27 |
+
]
|
| 28 |
+
}
|
modular_model_index.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_blocks_class_name": "Cosmos3DistilledBlocks",
|
| 3 |
+
"_class_name": "Cosmos3DistilledModularPipeline",
|
| 4 |
+
"_diffusers_version": "0.39.0",
|
| 5 |
+
"is_distilled": true,
|
| 6 |
+
"distilled_sigmas": [
|
| 7 |
+
1.0,
|
| 8 |
+
0.9375,
|
| 9 |
+
0.8333333333333334,
|
| 10 |
+
0.625
|
| 11 |
+
],
|
| 12 |
+
"scheduler": [
|
| 13 |
+
"diffusers",
|
| 14 |
+
"FlowMatchEulerDiscreteScheduler",
|
| 15 |
+
{
|
| 16 |
+
"pretrained_model_name_or_path": "nvidia/Cosmos3-Super-Image2Video-4Step",
|
| 17 |
+
"subfolder": "scheduler",
|
| 18 |
+
"type_hint": [
|
| 19 |
+
"diffusers",
|
| 20 |
+
"FlowMatchEulerDiscreteScheduler"
|
| 21 |
+
],
|
| 22 |
+
"variant": null
|
| 23 |
+
}
|
| 24 |
+
],
|
| 25 |
+
"text_tokenizer": [
|
| 26 |
+
"transformers",
|
| 27 |
+
"Qwen2TokenizerFast",
|
| 28 |
+
{
|
| 29 |
+
"pretrained_model_name_or_path": "nvidia/Cosmos3-Super-Image2Video-4Step",
|
| 30 |
+
"subfolder": "text_tokenizer",
|
| 31 |
+
"type_hint": [
|
| 32 |
+
"transformers",
|
| 33 |
+
"Qwen2TokenizerFast"
|
| 34 |
+
],
|
| 35 |
+
"variant": null
|
| 36 |
+
}
|
| 37 |
+
],
|
| 38 |
+
"transformer": [
|
| 39 |
+
"diffusers",
|
| 40 |
+
"Cosmos3OmniTransformer",
|
| 41 |
+
{
|
| 42 |
+
"pretrained_model_name_or_path": "nvidia/Cosmos3-Super-Image2Video-4Step",
|
| 43 |
+
"subfolder": "transformer",
|
| 44 |
+
"type_hint": [
|
| 45 |
+
"diffusers",
|
| 46 |
+
"Cosmos3OmniTransformer"
|
| 47 |
+
],
|
| 48 |
+
"variant": null
|
| 49 |
+
}
|
| 50 |
+
],
|
| 51 |
+
"vae": [
|
| 52 |
+
"diffusers",
|
| 53 |
+
"AutoencoderKLWan",
|
| 54 |
+
{
|
| 55 |
+
"pretrained_model_name_or_path": "nvidia/Cosmos3-Super-Image2Video-4Step",
|
| 56 |
+
"subfolder": "vae",
|
| 57 |
+
"type_hint": [
|
| 58 |
+
"diffusers",
|
| 59 |
+
"AutoencoderKLWan"
|
| 60 |
+
],
|
| 61 |
+
"variant": null
|
| 62 |
+
}
|
| 63 |
+
]
|
| 64 |
+
}
|
preprocessor_config.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"size": {
|
| 3 |
+
"longest_edge": 16777216,
|
| 4 |
+
"shortest_edge": 65536
|
| 5 |
+
},
|
| 6 |
+
"patch_size": 16,
|
| 7 |
+
"temporal_patch_size": 2,
|
| 8 |
+
"merge_size": 2,
|
| 9 |
+
"image_mean": [
|
| 10 |
+
0.5,
|
| 11 |
+
0.5,
|
| 12 |
+
0.5
|
| 13 |
+
],
|
| 14 |
+
"image_std": [
|
| 15 |
+
0.5,
|
| 16 |
+
0.5,
|
| 17 |
+
0.5
|
| 18 |
+
],
|
| 19 |
+
"processor_class": "Qwen3VLProcessor",
|
| 20 |
+
"image_processor_type": "Qwen2VLImageProcessorFast"
|
| 21 |
+
}
|
quantize_cosmos3_i2v4step_streaming.py
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""
|
| 3 |
+
Stream-quantize NVIDIA Cosmos3-Super-Image2Video-4Step's transformer to weight-only
|
| 4 |
+
FP8 or NVFP4, WITHOUT ever materializing the full ~128 GB BF16 model.
|
| 5 |
+
|
| 6 |
+
This is the same-architecture sibling of quantize_cosmos3_super_streaming.py (the
|
| 7 |
+
recipe validated against nvidia/Cosmos3-Super): identical Cosmos3OmniTransformer
|
| 8 |
+
class, identical dims (64 layers, hidden_size 5120), so the empty-on-meta ->
|
| 9 |
+
mtq.quantize -> mtq.compress -> stream-load recipe and the SPARE_SUBSTRINGS list
|
| 10 |
+
carry over unchanged. Three things do NOT carry over -- this checkpoint is a DMD2
|
| 11 |
+
4-step distillation of Cosmos3-Super-Image2Video, and differs as follows:
|
| 12 |
+
|
| 13 |
+
1. SCHEDULER IS FIXED, NOT SWAPPABLE. The base-model script (and
|
| 14 |
+
serve_cosmos3_diffusers.py) replace the shipped scheduler with
|
| 15 |
+
UniPCMultistepScheduler(flow_shift=...). This checkpoint ships
|
| 16 |
+
FlowMatchEulerDiscreteScheduler with a baked-in fixed_step_sampler_config
|
| 17 |
+
(sde sampling, t_list=[1.0, 0.9375, 0.8333, 0.625] -- literally 4 steps).
|
| 18 |
+
Do NOT override it -- use pipe.scheduler as loaded.
|
| 19 |
+
2. num_inference_steps / guidance_scale are NOT meaningfully configurable per
|
| 20 |
+
NVIDIA's model card (CFG is distilled out; the checkpoint was trained for an
|
| 21 |
+
exact 4-step sde schedule). CONFIRMED BY RUNNING IT: Cosmos3OmniPipeline
|
| 22 |
+
(diffusers 0.39.0.dev0) does not know this checkpoint's scheduler carries a
|
| 23 |
+
fixed_step_sampler_config -- an unpatched call silently ran the pipeline's
|
| 24 |
+
35-step/guidance=6.0 default instead. render_from_memory() below patches the
|
| 25 |
+
scheduler (_force_fixed_step_schedule) to force the correct 4-step t_list and
|
| 26 |
+
passes guidance_scale=1.0 explicitly. See that function's docstring.
|
| 27 |
+
3. This checkpoint is Image2Video-specific (unlike the T2I/T2V/I2V-omni base
|
| 28 |
+
model), so the smoke render requires a conditioning IMAGE -- there is no
|
| 29 |
+
text-only still-image path to fall back on. sound_tokenizer is also null in
|
| 30 |
+
this repo (audio branch inactive), so the "audio_proj" spare substring is
|
| 31 |
+
believed inert here, but is kept for parity/safety.
|
| 32 |
+
|
| 33 |
+
USAGE
|
| 34 |
+
-----
|
| 35 |
+
python quantize_cosmos3_i2v4step_streaming.py --format fp8
|
| 36 |
+
python quantize_cosmos3_i2v4step_streaming.py --format fp8 --smoke --image out.png
|
| 37 |
+
|
| 38 |
+
Outputs go to ./cosmos3-i2v4step-<fmt>/ (override with --export-dir).
|
| 39 |
+
"""
|
| 40 |
+
|
| 41 |
+
import argparse
|
| 42 |
+
import os
|
| 43 |
+
|
| 44 |
+
# Reduce allocator fragmentation on the big card (cheap, always-on).
|
| 45 |
+
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
|
| 46 |
+
|
| 47 |
+
import torch
|
| 48 |
+
from accelerate import init_empty_weights, load_checkpoint_in_model
|
| 49 |
+
from accelerate.utils import get_max_memory, infer_auto_device_map
|
| 50 |
+
from accelerate.utils.dataclasses import CustomDtype
|
| 51 |
+
from huggingface_hub import snapshot_download
|
| 52 |
+
|
| 53 |
+
import modelopt.torch.quantization as mtq
|
| 54 |
+
from modelopt.torch.export import export_hf_checkpoint
|
| 55 |
+
|
| 56 |
+
# Cosmos3 classes require diffusers built from git main (already installed in the venv).
|
| 57 |
+
from diffusers import Cosmos3OmniTransformer
|
| 58 |
+
|
| 59 |
+
SRC_REPO = "nvidia/Cosmos3-Super-Image2Video-4Step"
|
| 60 |
+
|
| 61 |
+
# ---------------------------------------------------------------------------
|
| 62 |
+
# Layers to KEEP IN BF16 (never quantize). Matched as substrings of module names.
|
| 63 |
+
# Unchanged from the base-model recipe -- same transformer class + dims, so the
|
| 64 |
+
# same layers are quality-sensitive: embeddings, norms, the bundled Qwen3 reasoner
|
| 65 |
+
# head, time/modality adapters, and the in/out projections.
|
| 66 |
+
# ---------------------------------------------------------------------------
|
| 67 |
+
SPARE_SUBSTRINGS = [
|
| 68 |
+
"time_embedder",
|
| 69 |
+
"proj_in",
|
| 70 |
+
"proj_out",
|
| 71 |
+
"lm_head",
|
| 72 |
+
"embed", # token / position embeddings
|
| 73 |
+
"norm", # layernorms / rmsnorms
|
| 74 |
+
"audio_proj", # audio modality adapter (inert here: sound_tokenizer is null)
|
| 75 |
+
]
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
def _is_spare(module_name: str) -> bool:
|
| 79 |
+
return any(s in module_name for s in SPARE_SUBSTRINGS)
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def build_quant_cfg(fmt: str) -> dict:
|
| 83 |
+
"""Return a WEIGHT-ONLY quant config for the chosen format. Same as the
|
| 84 |
+
base-model recipe: FP8 per-tensor E4M3, or NVFP4 4-bit block-scale."""
|
| 85 |
+
if fmt == "fp8":
|
| 86 |
+
return {
|
| 87 |
+
"quant_cfg": {
|
| 88 |
+
"*weight_quantizer": {"num_bits": (4, 3), "axis": None, "enable": True},
|
| 89 |
+
"*input_quantizer": {"enable": False},
|
| 90 |
+
"*output_quantizer": {"enable": False},
|
| 91 |
+
"*softmax_quantizer": {"enable": False},
|
| 92 |
+
},
|
| 93 |
+
"algorithm": "max",
|
| 94 |
+
}
|
| 95 |
+
elif fmt == "nvfp4":
|
| 96 |
+
import copy
|
| 97 |
+
|
| 98 |
+
base = getattr(mtq, "W4A16_NVFP4_CFG", None) or mtq.NVFP4_DEFAULT_CFG
|
| 99 |
+
return copy.deepcopy(base)
|
| 100 |
+
else:
|
| 101 |
+
raise ValueError(f"Unknown format: {fmt!r}")
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def enforce_weight_only_and_spare(model) -> tuple[int, int]:
|
| 105 |
+
"""Disable all activation quantizers, and weight quantizers on SPARE layers.
|
| 106 |
+
Config-form agnostic (works for both the FP8 dict and modelopt's NVFP4 preset)."""
|
| 107 |
+
n_spare = 0
|
| 108 |
+
n_act = 0
|
| 109 |
+
for name, module in model.named_modules():
|
| 110 |
+
if not (name.endswith("_quantizer") and hasattr(module, "disable")):
|
| 111 |
+
continue
|
| 112 |
+
if name.endswith("weight_quantizer"):
|
| 113 |
+
parent = name.rsplit(".", 1)[0]
|
| 114 |
+
if _is_spare(parent):
|
| 115 |
+
module.disable()
|
| 116 |
+
n_spare += 1
|
| 117 |
+
else:
|
| 118 |
+
module.disable()
|
| 119 |
+
n_act += 1
|
| 120 |
+
return n_spare, n_act
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def compressed_device_map(model, gpu_mem_fraction: float = 0.85) -> dict:
|
| 124 |
+
"""Build a device_map sized for the COMPRESSED weights (same as base-model recipe)."""
|
| 125 |
+
max_memory = {k: v * gpu_mem_fraction for k, v in get_max_memory().items()}
|
| 126 |
+
|
| 127 |
+
no_split = set()
|
| 128 |
+
for name, module in model.named_modules():
|
| 129 |
+
if name.endswith((".layers.0", ".blocks.0", ".transformer_blocks.0")):
|
| 130 |
+
no_split.add(module.__class__.__name__)
|
| 131 |
+
|
| 132 |
+
special_dtypes = {}
|
| 133 |
+
for name, module in model.named_modules():
|
| 134 |
+
if (
|
| 135 |
+
hasattr(module, "weight")
|
| 136 |
+
and hasattr(module, "weight_quantizer")
|
| 137 |
+
and getattr(module.weight_quantizer, "is_enabled", True)
|
| 138 |
+
and not getattr(module.weight_quantizer, "fake_quant", True)
|
| 139 |
+
):
|
| 140 |
+
nb = module.weight_quantizer.num_bits
|
| 141 |
+
if isinstance(nb, tuple):
|
| 142 |
+
nb = nb[0] + nb[1] + 1
|
| 143 |
+
special_dtypes[name + ".weight"] = CustomDtype.FP8 if nb == 8 else CustomDtype.INT4
|
| 144 |
+
|
| 145 |
+
return infer_auto_device_map(
|
| 146 |
+
model,
|
| 147 |
+
max_memory=max_memory,
|
| 148 |
+
no_split_module_classes=list(no_split),
|
| 149 |
+
special_dtypes=special_dtypes,
|
| 150 |
+
)
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
def main():
|
| 154 |
+
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
| 155 |
+
ap.add_argument("--format", choices=["fp8", "nvfp4"], required=True,
|
| 156 |
+
help="Weight-only quantization format to produce.")
|
| 157 |
+
ap.add_argument("--export-dir", default=None,
|
| 158 |
+
help="Output dir (default: ./cosmos3-i2v4step-<format>).")
|
| 159 |
+
ap.add_argument("--gpu-mem-fraction", type=float, default=0.85,
|
| 160 |
+
help="Fraction of each GPU's memory accelerate may use for placement.")
|
| 161 |
+
ap.add_argument("--smoke", action="store_true",
|
| 162 |
+
help="Validate by rendering a short clip from the in-memory model "
|
| 163 |
+
"(runs before export; output: cosmos3_i2v4step_<fmt>_validate.mp4).")
|
| 164 |
+
ap.add_argument("--image", default="out.png",
|
| 165 |
+
help="Conditioning image for the --smoke render (this checkpoint is "
|
| 166 |
+
"Image2Video-only -- there is no text-only still path).")
|
| 167 |
+
args = ap.parse_args()
|
| 168 |
+
|
| 169 |
+
export_dir = args.export_dir or f"./cosmos3-i2v4step-{args.format}"
|
| 170 |
+
os.makedirs(export_dir, exist_ok=True)
|
| 171 |
+
|
| 172 |
+
print(f"[1/6] Resolving local checkpoint for {SRC_REPO} (transformer only)...")
|
| 173 |
+
local_root = snapshot_download(SRC_REPO, allow_patterns=["transformer/*"])
|
| 174 |
+
transformer_dir = os.path.join(local_root, "transformer")
|
| 175 |
+
print(f" transformer dir: {transformer_dir}")
|
| 176 |
+
|
| 177 |
+
print("[2/6] Building EMPTY transformer on meta device (params on meta, buffers real)...")
|
| 178 |
+
config = Cosmos3OmniTransformer.load_config(transformer_dir)
|
| 179 |
+
with init_empty_weights(include_buffers=False):
|
| 180 |
+
model = Cosmos3OmniTransformer.from_config(config)
|
| 181 |
+
|
| 182 |
+
print(f"[3/6] Inserting quantizers ({args.format}) on the meta model...")
|
| 183 |
+
quant_cfg = build_quant_cfg(args.format)
|
| 184 |
+
mtq.quantize(model, quant_cfg) # no forward_loop: weight-only needs no calibration
|
| 185 |
+
n_spare, n_act = enforce_weight_only_and_spare(model)
|
| 186 |
+
print(f" weight-only: disabled {n_act} activation quantizers; "
|
| 187 |
+
f"kept {n_spare} projection layers in BF16 (plus embeddings/norms/head)")
|
| 188 |
+
|
| 189 |
+
print("[4/6] Setting up compressed parameter shapes (mtq.compress)...")
|
| 190 |
+
try:
|
| 191 |
+
mtq.compress(model, config=mtq.CompressConfig(quant_gemm=False))
|
| 192 |
+
except (AttributeError, TypeError):
|
| 193 |
+
mtq.compress(model)
|
| 194 |
+
|
| 195 |
+
print("[5/6] Streaming BF16 shards into compressed form (this is the long step)...")
|
| 196 |
+
device_map = compressed_device_map(model, args.gpu_mem_fraction)
|
| 197 |
+
load_checkpoint_in_model(
|
| 198 |
+
model,
|
| 199 |
+
checkpoint=transformer_dir,
|
| 200 |
+
device_map=device_map,
|
| 201 |
+
dtype=torch.bfloat16,
|
| 202 |
+
)
|
| 203 |
+
|
| 204 |
+
n_fixed = 0
|
| 205 |
+
for _, module in model.named_modules():
|
| 206 |
+
for bname, buf in list(module._buffers.items()):
|
| 207 |
+
if buf is not None and getattr(buf, "is_meta", False):
|
| 208 |
+
module._buffers[bname] = torch.zeros(buf.shape, dtype=buf.dtype, device="cuda")
|
| 209 |
+
n_fixed += 1
|
| 210 |
+
for pname, par in list(module._parameters.items()):
|
| 211 |
+
if par is not None and getattr(par, "is_meta", False):
|
| 212 |
+
module._parameters[pname] = torch.nn.Parameter(
|
| 213 |
+
torch.zeros(par.shape, dtype=par.dtype, device="cuda"), requires_grad=False
|
| 214 |
+
)
|
| 215 |
+
n_fixed += 1
|
| 216 |
+
if n_fixed:
|
| 217 |
+
print(f" materialized {n_fixed} residual meta tensors (disabled-quantizer scratch)")
|
| 218 |
+
|
| 219 |
+
n_bytes = sum(p.numel() * p.element_size() for p in model.parameters() if p.device.type != "meta")
|
| 220 |
+
n_bytes += sum(b.numel() * b.element_size() for b in model.buffers() if b.device.type != "meta")
|
| 221 |
+
print(f" live footprint: {n_bytes / 1e9:.1f} GB")
|
| 222 |
+
|
| 223 |
+
if args.smoke:
|
| 224 |
+
render_from_memory(model, args.format, args.image)
|
| 225 |
+
|
| 226 |
+
print(f"[6/6] Exporting unified HF checkpoint to {export_dir} ...")
|
| 227 |
+
with torch.inference_mode():
|
| 228 |
+
export_hf_checkpoint(model, export_dir=export_dir)
|
| 229 |
+
print(f"DONE. Quantized {args.format.upper()} checkpoint written to {export_dir}")
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
def _force_fixed_step_schedule(scheduler) -> bool:
|
| 233 |
+
"""CONFIRMED (not speculative): Cosmos3OmniPipeline.__call__ always calls
|
| 234 |
+
scheduler.set_timesteps(num_inference_steps, device=device) with no sigmas
|
| 235 |
+
passthrough (pipeline_cosmos3_omni.py:1529 in diffusers 0.39.0.dev0), so this
|
| 236 |
+
checkpoint's scheduler_config.json fixed_step_sampler_config (t_list) is silently
|
| 237 |
+
dropped -- an unpatched call falls back to the pipeline's num_inference_steps=35
|
| 238 |
+
default (verified empirically: a real run produced a 35-step progress bar despite
|
| 239 |
+
this being a 4-step DMD2-distilled checkpoint). Running any schedule other than the
|
| 240 |
+
exact trained t_list is off-distribution for what the model was distilled to
|
| 241 |
+
denoise, so patch THIS scheduler instance's set_timesteps to always use it,
|
| 242 |
+
regardless of whatever num_inference_steps the pipeline passes in.
|
| 243 |
+
|
| 244 |
+
ALSO disables stochastic_sampling (forces the deterministic ODE branch) -- CONFIRMED
|
| 245 |
+
by direct A/B render, not speculative. This checkpoint ships stochastic_sampling=True
|
| 246 |
+
(SDE sampling). Cosmos3's image-conditioning anchors frame 0 by zeroing the model's
|
| 247 |
+
predicted velocity there (_mask_velocity_predictions), which only means "leave this
|
| 248 |
+
position unchanged" under the DETERMINISTIC step (prev_sample = sample + dt*0 =
|
| 249 |
+
sample). The SDE branch instead computes
|
| 250 |
+
x0 = sample - current_sigma * model_output # = sample when velocity is 0
|
| 251 |
+
prev_sample = (1 - next_sigma) * x0 + next_sigma * randn_tensor(...)
|
| 252 |
+
which re-noises the sample by next_sigma regardless of velocity -- there is no
|
| 253 |
+
zero-velocity no-op in the SDE formula. Across this checkpoint's 4 steps that
|
| 254 |
+
compounds to ~99.6% fresh noise by the final step: the conditioning image is
|
| 255 |
+
destroyed into colorful static while the (non-anchored, genuinely denoised) motion
|
| 256 |
+
frames still look like a plausible video. Disabling stochastic_sampling makes zero
|
| 257 |
+
velocity a true no-op again, which an A/B render (same seed/image/prompt) confirmed
|
| 258 |
+
fixes it outright. This is presumably NVIDIA's own reference runtime doing a masked
|
| 259 |
+
resample this diffusers pipeline port doesn't implement; revisit if that lands
|
| 260 |
+
upstream."""
|
| 261 |
+
cfg = getattr(scheduler.config, "fixed_step_sampler_config", None)
|
| 262 |
+
t_list = cfg.get("t_list") if isinstance(cfg, dict) else None
|
| 263 |
+
if not t_list:
|
| 264 |
+
print("[warn] no fixed_step_sampler_config.t_list on this scheduler; leaving set_timesteps unpatched")
|
| 265 |
+
return False
|
| 266 |
+
_orig = scheduler.set_timesteps
|
| 267 |
+
|
| 268 |
+
def _patched(num_inference_steps=None, device=None, sigmas=None, mu=None, timesteps=None):
|
| 269 |
+
return _orig(sigmas=list(t_list), device=device)
|
| 270 |
+
|
| 271 |
+
scheduler.set_timesteps = _patched
|
| 272 |
+
if getattr(scheduler.config, "stochastic_sampling", False):
|
| 273 |
+
scheduler.register_to_config(stochastic_sampling=False)
|
| 274 |
+
print("[patch] disabled stochastic_sampling (SDE re-noising corrupts the "
|
| 275 |
+
"image-conditioned frame -- see docstring)")
|
| 276 |
+
print(f"[patch] forced fixed {len(t_list)}-step sde schedule: {t_list}")
|
| 277 |
+
return True
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
def render_from_memory(model, fmt: str, image_path: str):
|
| 281 |
+
"""Validate the quantization by rendering an image->video clip from the IN-MEMORY
|
| 282 |
+
model. Does NOT swap the scheduler object itself (keeps FlowMatchEulerDiscreteScheduler
|
| 283 |
+
with its stochastic_sampling config), but DOES patch its set_timesteps via
|
| 284 |
+
_force_fixed_step_schedule -- see that function for why this is required rather than
|
| 285 |
+
optional. guidance_scale=1.0 is passed explicitly: CFG is distilled out of this
|
| 286 |
+
checkpoint (do_classifier_free_guidance is guidance_scale != 1.0 in the pipeline
|
| 287 |
+
source), and the 6.0 pipeline default would silently re-enable it."""
|
| 288 |
+
import gc
|
| 289 |
+
|
| 290 |
+
print(f"\n[validate] Rendering an image->video clip from the in-memory {fmt.upper()} model "
|
| 291 |
+
f"(conditioning image: {image_path})...")
|
| 292 |
+
try:
|
| 293 |
+
from PIL import Image
|
| 294 |
+
|
| 295 |
+
from diffusers import Cosmos3OmniPipeline
|
| 296 |
+
|
| 297 |
+
if not os.path.isfile(image_path):
|
| 298 |
+
raise FileNotFoundError(
|
| 299 |
+
f"conditioning image {image_path!r} not found -- pass --image with a real "
|
| 300 |
+
"file; this checkpoint has no text-only still path to fall back on."
|
| 301 |
+
)
|
| 302 |
+
cond_image = Image.open(image_path).convert("RGB")
|
| 303 |
+
|
| 304 |
+
model.to("cuda")
|
| 305 |
+
|
| 306 |
+
# Dtype consistency at render time (same nudge as the base-model script): our
|
| 307 |
+
# model mixes FP8/NVFP4 (compressed) weights with BF16 spare weights, while
|
| 308 |
+
# diffusers computes the timestep sinusoidal fresh in FP32 each step.
|
| 309 |
+
for _module in model.modules():
|
| 310 |
+
for _bn, _buf in list(_module._buffers.items()):
|
| 311 |
+
if _buf is not None and _buf.dtype == torch.float32:
|
| 312 |
+
_module._buffers[_bn] = _buf.to(torch.bfloat16)
|
| 313 |
+
|
| 314 |
+
def _cast_inputs_bf16(_m, args):
|
| 315 |
+
return tuple(
|
| 316 |
+
a.to(torch.bfloat16)
|
| 317 |
+
if torch.is_tensor(a) and a.is_floating_point() and a.dtype != torch.bfloat16
|
| 318 |
+
else a
|
| 319 |
+
for a in args
|
| 320 |
+
)
|
| 321 |
+
|
| 322 |
+
n_hooks = 0
|
| 323 |
+
for _name, _module in model.named_modules():
|
| 324 |
+
if "time_embedder" in _name and hasattr(_module, "linear_1"):
|
| 325 |
+
_module.register_forward_pre_hook(_cast_inputs_bf16)
|
| 326 |
+
n_hooks += 1
|
| 327 |
+
print(f"[validate] dtype-safety: cast fp32 buffers to bf16, hooked {n_hooks} time-embedder(s)")
|
| 328 |
+
|
| 329 |
+
# Pass OUR quantized transformer in so the pipeline does NOT reload it from the hub.
|
| 330 |
+
# Deliberately do NOT touch pipe.scheduler -- the shipped FlowMatchEulerDiscreteScheduler
|
| 331 |
+
# carries the fixed 4-step sde schedule for this checkpoint.
|
| 332 |
+
pipe = Cosmos3OmniPipeline.from_pretrained(
|
| 333 |
+
SRC_REPO,
|
| 334 |
+
transformer=model,
|
| 335 |
+
torch_dtype=torch.bfloat16,
|
| 336 |
+
enable_safety_checker=False,
|
| 337 |
+
)
|
| 338 |
+
for name, comp in pipe.components.items():
|
| 339 |
+
if name != "transformer" and isinstance(comp, torch.nn.Module):
|
| 340 |
+
comp.to("cuda")
|
| 341 |
+
|
| 342 |
+
_force_fixed_step_schedule(pipe.scheduler)
|
| 343 |
+
|
| 344 |
+
prompt = (
|
| 345 |
+
"The camera holds static as the scene continues naturally, with subtle "
|
| 346 |
+
"motion and realistic physics."
|
| 347 |
+
)
|
| 348 |
+
with torch.inference_mode():
|
| 349 |
+
# num_inference_steps is a no-op once _force_fixed_step_schedule has patched
|
| 350 |
+
# set_timesteps (it always substitutes the checkpoint's own t_list), but is
|
| 351 |
+
# passed for clarity. guidance_scale=1.0 disables CFG -- see docstring above.
|
| 352 |
+
# 13 frames (4n+1) keeps the smoke test quick; bump for a real quality check.
|
| 353 |
+
result = pipe(
|
| 354 |
+
prompt=prompt,
|
| 355 |
+
negative_prompt="",
|
| 356 |
+
image=cond_image,
|
| 357 |
+
num_frames=13,
|
| 358 |
+
height=256,
|
| 359 |
+
width=256,
|
| 360 |
+
num_inference_steps=4,
|
| 361 |
+
guidance_scale=1.0,
|
| 362 |
+
generator=torch.Generator(device="cuda").manual_seed(1234),
|
| 363 |
+
)
|
| 364 |
+
out_path = f"cosmos3_i2v4step_{fmt}_validate.mp4"
|
| 365 |
+
from diffusers.utils import export_to_video
|
| 366 |
+
export_to_video(result.video, out_path, fps=24)
|
| 367 |
+
print(f"[validate] Wrote {out_path}. Eyeball it for coherence with the conditioning image.")
|
| 368 |
+
|
| 369 |
+
del pipe, result
|
| 370 |
+
gc.collect()
|
| 371 |
+
torch.cuda.empty_cache()
|
| 372 |
+
except Exception as e:
|
| 373 |
+
import traceback
|
| 374 |
+
print(f"[validate] Render failed ({type(e).__name__}: {e}).")
|
| 375 |
+
print("[validate] This does NOT affect the quantized weights; export still proceeds below.")
|
| 376 |
+
print("[validate] If this is a TypeError about an unexpected keyword argument, that's real "
|
| 377 |
+
"signal about this checkpoint's actual pipe() call shape -- adjust the call above "
|
| 378 |
+
"(e.g. drop/rename kwargs) rather than assuming the defaults here were correct.")
|
| 379 |
+
traceback.print_exc()
|
| 380 |
+
|
| 381 |
+
|
| 382 |
+
if __name__ == "__main__":
|
| 383 |
+
main()
|
repackage_for_hf_i2v4step.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""
|
| 3 |
+
Re-save the in-memory quantized Cosmos3-Super-Image2Video-4Step transformer in the
|
| 4 |
+
ROUND-TRIPPABLE ModelOpt HF format and assemble a complete drop-in diffusers repo
|
| 5 |
+
around it. Sibling of repackage_for_hf.py -- identical logic, just imports the
|
| 6 |
+
build helpers from serve_cosmos3_i2v4step_diffusers instead (which targets
|
| 7 |
+
nvidia/Cosmos3-Super-Image2Video-4Step and drops the scheduler swap this
|
| 8 |
+
checkpoint doesn't want -- see that file's docstring).
|
| 9 |
+
|
| 10 |
+
Run in the ModelOpt venv, from the directory containing serve_cosmos3_i2v4step_diffusers.py:
|
| 11 |
+
CUDA_VISIBLE_DEVICES=0 python repackage_for_hf_i2v4step.py --format fp8 \
|
| 12 |
+
--serve-dir ./cosmos3-i2v4step-fp8-serve \
|
| 13 |
+
--out-dir ./cosmos3-i2v4step-fp8-hf \
|
| 14 |
+
[--cache ./cosmos3-i2v4step-cache]
|
| 15 |
+
|
| 16 |
+
Then verify the result loads + renders:
|
| 17 |
+
python -i load_cosmos3_modelopt.py ./cosmos3-i2v4step-fp8-hf
|
| 18 |
+
"""
|
| 19 |
+
import argparse
|
| 20 |
+
import json
|
| 21 |
+
import os
|
| 22 |
+
import pathlib
|
| 23 |
+
import shutil
|
| 24 |
+
|
| 25 |
+
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
|
| 26 |
+
|
| 27 |
+
import torch # noqa: F401 (ensures CUDA init / dtype availability)
|
| 28 |
+
from modelopt.torch.opt import enable_huggingface_checkpointing
|
| 29 |
+
|
| 30 |
+
from serve_cosmos3_i2v4step_diffusers import build_quantized_transformer, try_restore_quantized
|
| 31 |
+
|
| 32 |
+
QUANT_TYPE = {"fp8": "FP8", "nvfp4": "NVFP4"}
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def ensure_loadable_config(transformer_dir: str, fmt: str) -> None:
|
| 36 |
+
"""If save_pretrained wrote a quantization_config, make sure diffusers can construct
|
| 37 |
+
it: NVIDIAModelOptConfig needs `quant_type`, and a truthy `modelopt_config` avoids the
|
| 38 |
+
buggy get_config_from_quant_type() builder. (Structure restore itself comes from
|
| 39 |
+
modelopt_state.pth; this just keeps config parsing from crashing on load.)"""
|
| 40 |
+
cfg_path = pathlib.Path(transformer_dir) / "config.json"
|
| 41 |
+
cfg = json.loads(cfg_path.read_text())
|
| 42 |
+
qc = cfg.get("quantization_config")
|
| 43 |
+
if isinstance(qc, dict):
|
| 44 |
+
qc["quant_type"] = QUANT_TYPE[fmt]
|
| 45 |
+
qc.setdefault("weight_only", True)
|
| 46 |
+
if not qc.get("modelopt_config"):
|
| 47 |
+
qc["modelopt_config"] = {"quant_cfg": {}, "algorithm": "max"}
|
| 48 |
+
cfg["quantization_config"] = qc
|
| 49 |
+
cfg_path.write_text(json.dumps(cfg, indent=2))
|
| 50 |
+
print(f"[patch] quantization_config made loadable (quant_type={qc['quant_type']})")
|
| 51 |
+
else:
|
| 52 |
+
print("[patch] no embedded quantization_config; relying on modelopt_state.pth for restore")
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def main() -> None:
|
| 56 |
+
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
| 57 |
+
ap.add_argument("--format", choices=["fp8", "nvfp4"], default="fp8")
|
| 58 |
+
ap.add_argument("--serve-dir", required=True,
|
| 59 |
+
help="existing assembled pipeline dir (source of VAE / tokenizers / model_index.json)")
|
| 60 |
+
ap.add_argument("--out-dir", required=True, help="new drop-in repo dir to create")
|
| 61 |
+
ap.add_argument("--cache", default=None, help="optional mto cache dir for a faster rebuild")
|
| 62 |
+
ap.add_argument("--gpu-mem-fraction", type=float, default=0.85)
|
| 63 |
+
args = ap.parse_args()
|
| 64 |
+
|
| 65 |
+
model = try_restore_quantized(args.format, args.cache) if args.cache else None
|
| 66 |
+
if model is None:
|
| 67 |
+
model = build_quantized_transformer(args.format, args.gpu_mem_fraction)
|
| 68 |
+
|
| 69 |
+
enable_huggingface_checkpointing()
|
| 70 |
+
tdir = os.path.join(args.out_dir, "transformer")
|
| 71 |
+
os.makedirs(tdir, exist_ok=True)
|
| 72 |
+
print(f"[save] writing round-trippable transformer (+ modelopt_state.pth) -> {tdir}")
|
| 73 |
+
model.save_pretrained(tdir)
|
| 74 |
+
state_file = os.path.join(tdir, "modelopt_state.pth")
|
| 75 |
+
assert os.path.isfile(state_file), (
|
| 76 |
+
f"expected {state_file} to exist -- enable_huggingface_checkpointing() must run "
|
| 77 |
+
"before save_pretrained(); without modelopt_state.pth the repo won't load in diffusers"
|
| 78 |
+
)
|
| 79 |
+
ensure_loadable_config(tdir, args.format)
|
| 80 |
+
|
| 81 |
+
print(f"[assemble] copying non-transformer components from {args.serve_dir}")
|
| 82 |
+
for name in os.listdir(args.serve_dir):
|
| 83 |
+
if name == "transformer":
|
| 84 |
+
continue
|
| 85 |
+
src = os.path.join(args.serve_dir, name)
|
| 86 |
+
dst = os.path.join(args.out_dir, name)
|
| 87 |
+
if os.path.isdir(src):
|
| 88 |
+
shutil.copytree(src, dst, dirs_exist_ok=True)
|
| 89 |
+
else:
|
| 90 |
+
shutil.copy2(src, dst)
|
| 91 |
+
|
| 92 |
+
print(f"[done] drop-in repo -> {args.out_dir}")
|
| 93 |
+
print(f" verify: python -i load_cosmos3_modelopt.py {args.out_dir}")
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
if __name__ == "__main__":
|
| 97 |
+
main()
|
scheduler/scheduler_config.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_class_name": "FlowMatchEulerDiscreteScheduler",
|
| 3 |
+
"_diffusers_version": "0.39.0",
|
| 4 |
+
"base_image_seq_len": 256,
|
| 5 |
+
"base_shift": 0.5,
|
| 6 |
+
"fixed_step_requires_explicit_sigmas": true,
|
| 7 |
+
"fixed_step_sampler_config": {
|
| 8 |
+
"sample_type": "sde",
|
| 9 |
+
"t_list": [
|
| 10 |
+
1.0,
|
| 11 |
+
0.9375,
|
| 12 |
+
0.8333333333333334,
|
| 13 |
+
0.625
|
| 14 |
+
]
|
| 15 |
+
},
|
| 16 |
+
"invert_sigmas": false,
|
| 17 |
+
"max_image_seq_len": 4096,
|
| 18 |
+
"max_shift": 1.15,
|
| 19 |
+
"num_train_timesteps": 1000,
|
| 20 |
+
"shift": 1.0,
|
| 21 |
+
"shift_terminal": null,
|
| 22 |
+
"stochastic_sampling": true,
|
| 23 |
+
"time_shift_type": "exponential",
|
| 24 |
+
"use_beta_sigmas": false,
|
| 25 |
+
"use_dynamic_shifting": false,
|
| 26 |
+
"use_exponential_sigmas": false,
|
| 27 |
+
"use_karras_sigmas": false
|
| 28 |
+
}
|
scripts/gen_video.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Minimal image-to-video generation against a vLLM-Omni endpoint (sync mode).
|
| 2 |
+
|
| 3 |
+
Run from the Cosmos3-Super-Image2Video-4Step repo root:
|
| 4 |
+
|
| 5 |
+
python scripts/gen_video.py \
|
| 6 |
+
--prompt-file assets/example_prompt.json \
|
| 7 |
+
--image-path assets/example_first_frame.png \
|
| 8 |
+
--output-path scripts/output.mp4
|
| 9 |
+
|
| 10 |
+
Use --endpoint http://<server-host>:8000 if the vLLM-Omni server is not local.
|
| 11 |
+
"""
|
| 12 |
+
|
| 13 |
+
import argparse
|
| 14 |
+
import json
|
| 15 |
+
from pathlib import Path
|
| 16 |
+
|
| 17 |
+
import requests
|
| 18 |
+
|
| 19 |
+
# Fixed generation settings: 16:9 480p, 189 frames @ 24 fps.
|
| 20 |
+
ASPECT_RATIO = "16,9"
|
| 21 |
+
WIDTH = 832
|
| 22 |
+
HEIGHT = 480
|
| 23 |
+
NUM_FRAMES = 189
|
| 24 |
+
FPS = 24
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def main() -> None:
|
| 28 |
+
parser = argparse.ArgumentParser(description="Generate one I2V sample (sync mode).")
|
| 29 |
+
parser.add_argument("--endpoint", default="http://localhost:8000", help="vLLM-Omni endpoint base URL.")
|
| 30 |
+
parser.add_argument("--prompt-file", type=Path, default=Path("assets/example_prompt.json"))
|
| 31 |
+
parser.add_argument("--image-path", type=Path, default=Path("assets/example_first_frame.png"))
|
| 32 |
+
parser.add_argument("--output-path", type=Path, default=Path("scripts/output.mp4"))
|
| 33 |
+
args = parser.parse_args()
|
| 34 |
+
|
| 35 |
+
spec = json.loads(args.prompt_file.read_text(encoding="utf-8"))
|
| 36 |
+
prompt = json.loads(spec["prompt"])
|
| 37 |
+
prompt["duration"] = f"{int(NUM_FRAMES / FPS)}s"
|
| 38 |
+
prompt["fps"] = float(round(FPS))
|
| 39 |
+
prompt["resolution"] = {"H": HEIGHT, "W": WIDTH}
|
| 40 |
+
prompt["aspect_ratio"] = ASPECT_RATIO
|
| 41 |
+
|
| 42 |
+
request_body = {
|
| 43 |
+
"prompt": json.dumps(prompt, ensure_ascii=False),
|
| 44 |
+
"negative_prompt": spec["negative_prompt"],
|
| 45 |
+
"size": f"{WIDTH}x{HEIGHT}",
|
| 46 |
+
"num_frames": NUM_FRAMES,
|
| 47 |
+
"fps": FPS,
|
| 48 |
+
"guidance_scale": 1.0,
|
| 49 |
+
"extra_params": json.dumps(
|
| 50 |
+
{
|
| 51 |
+
"guardrails": True,
|
| 52 |
+
"use_resolution_template": False,
|
| 53 |
+
"use_duration_template": False,
|
| 54 |
+
}
|
| 55 |
+
),
|
| 56 |
+
}
|
| 57 |
+
files = {"input_reference": ("input.png", args.image_path.read_bytes(), "image/png")}
|
| 58 |
+
headers = {"Accept": "video/mp4", "User-Agent": "curl/8.5.0"}
|
| 59 |
+
|
| 60 |
+
endpoint = args.endpoint.rstrip("/")
|
| 61 |
+
response = requests.post(
|
| 62 |
+
f"{endpoint}/v1/videos/sync",
|
| 63 |
+
data=request_body,
|
| 64 |
+
files=files,
|
| 65 |
+
headers=headers,
|
| 66 |
+
timeout=(10, 600),
|
| 67 |
+
)
|
| 68 |
+
response.raise_for_status()
|
| 69 |
+
|
| 70 |
+
args.output_path.parent.mkdir(parents=True, exist_ok=True)
|
| 71 |
+
args.output_path.write_bytes(response.content)
|
| 72 |
+
print(f"Saved video to {args.output_path} ({len(response.content) / (1024 * 1024):.1f} MB)")
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
if __name__ == "__main__":
|
| 76 |
+
main()
|
scripts/upsample_prompt.py
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Minimal image-to-video prompt upsampler.
|
| 2 |
+
|
| 3 |
+
Run from the Cosmos3-Super-Image2Video-4Step repo root:
|
| 4 |
+
|
| 5 |
+
export PROMPT_UPSAMPLER_API_KEY="..."
|
| 6 |
+
python scripts/upsample_prompt.py \
|
| 7 |
+
--model-name <model> \
|
| 8 |
+
--base-url <VLM-endpoint-url> \
|
| 9 |
+
--image-path assets/example_first_frame.png \
|
| 10 |
+
--user-prompt "The dog flies into the outer space" \
|
| 11 |
+
--output-path scripts/upsampled.json
|
| 12 |
+
"""
|
| 13 |
+
|
| 14 |
+
import argparse
|
| 15 |
+
import base64
|
| 16 |
+
import json
|
| 17 |
+
import mimetypes
|
| 18 |
+
import os
|
| 19 |
+
import re
|
| 20 |
+
from pathlib import Path
|
| 21 |
+
|
| 22 |
+
import requests
|
| 23 |
+
|
| 24 |
+
# Fixed generation settings: 16:9 480p, 189 frames @ 24 fps.
|
| 25 |
+
ASPECT_RATIO = "16,9"
|
| 26 |
+
WIDTH = 832
|
| 27 |
+
HEIGHT = 480
|
| 28 |
+
NUM_FRAMES = 189
|
| 29 |
+
FPS = 24
|
| 30 |
+
|
| 31 |
+
MAX_TOKENS = 8192
|
| 32 |
+
|
| 33 |
+
PROMPT_TEMPLATE = """You are an expert prompt engineer for an image-to-video generative model. You are given a STARTING FRAME image (the first frame of the video) and a USER INSTRUCTION describing the desired motion or changes to animate. Your task is to produce a dense, cinematic video description that the model will use to generate the full video, together with a customized negative prompt.
|
| 34 |
+
|
| 35 |
+
Complete this task in two phases.
|
| 36 |
+
|
| 37 |
+
---
|
| 38 |
+
### PHASE 1: VIDEO DESCRIPTION
|
| 39 |
+
Write a dense, narrative temporal_caption inside `<final_prompt>` XML tags, formatted as a JSON object using this exact template:
|
| 40 |
+
|
| 41 |
+
{
|
| 42 |
+
"temporal_caption": "...",
|
| 43 |
+
"duration": "placeholder",
|
| 44 |
+
"fps": "placeholder",
|
| 45 |
+
"resolution": {
|
| 46 |
+
"H": "placeholder",
|
| 47 |
+
"W": "placeholder"
|
| 48 |
+
},
|
| 49 |
+
"aspect_ratio": "placeholder"
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
Rules for the temporal_caption:
|
| 53 |
+
- The provided image is the exact starting frame - all described motion must be consistent with the starting frame.
|
| 54 |
+
- Opening: Establish the scene — subjects, environment, lighting — describing what is directly visible in the starting frame accurately and faithfully, noting essential elements that the motion will directly involve, the subject's orientation (e.g., "facing away", "in three-quarter profile"), and any implied ongoing motion (e.g., a cyclist leaning into a curve, water already splashing) so the video continues smoothly. Phrase it naturally as a scene description (do not say "in the starting frame", "initially shown", or similar meta-references).
|
| 55 |
+
- Motion: Describe the changes and actions in chronological order. Flow naturally from one action to the next. Advance time using natural conjunctions (e.g., "while," "as," "and").
|
| 56 |
+
- Physical Accuracy: All motion must obey gravity and reflect realistic material behavior (e.g., cloth ripples, water splashes, rigid objects resist deformation).
|
| 57 |
+
- Cause-and-effect: Always describe causes before their effects. Reflections, shadows, and secondary effects cannot appear on their own — the source object must first enter the frame or move into the relevant position before any reflection or shadow is described. E.g., a person must walk to the water's edge before their reflection appears on the surface; an object must strike the water before a splash erupts.
|
| 58 |
+
- Object Permanence: Every subject must persist throughout or have a clear reason for entering or exiting. When a new subject not present in the starting frame is introduced (e.g., an opposing team, an arriving vehicle), briefly describe their appearance (e.g., uniform color, vehicle type and color) so the generator can render them consistently, and describe a logical way for them to come into the frame (e.g., entering from a specific side of the frame, walking in through a door, or emerging from behind an existing object) rather than having them appear out of nowhere.
|
| 59 |
+
- Taboo Phrases: NEVER refer to the video medium itself. Avoid "the video shows...", "the scene...", "the clip...", "the frame...", "the camera shows...", "we see...".
|
| 60 |
+
- Perspective: Describe human body sides from the subject's own perspective (e.g., "her right hand" = the subject's right hand) to avoid ambiguity. This applies whenever a body part enters or moves in the frame: always specify whether it is the left or right (e.g., "his right hand reaches in from the lower edge"), never a bare "a hand enters the frame".
|
| 61 |
+
- Pronouns: Use singular pronouns ("he", "she", "him", "her", "it") or a singular noun phrase ("the person", "the rider", "the child") for single subjects. Never use "they"/"them"/"their" to refer to one person, as this can cause the model to render multiple subjects.
|
| 62 |
+
- Spatial Phrasing: Use spatial relationships for motion (e.g., "enters from the left", "rises above the horizon") rather than camera-centric descriptions.
|
| 63 |
+
- Camera: Include camera motion only if specified in the instruction; otherwise describe from a static viewpoint. Keep any described camera movement subtle and gradual — do not exaggerate altitude loss, tilt angle, or speed beyond what is minimally implied by the instruction. Do not use the word "transition" when describing camera motion.
|
| 64 |
+
- Cinematography Terms: When the instruction references a lens, camera, or filming technique (e.g., "probe lens", "macro lens", "fisheye", "drone shot", "GoPro"), treat it as a cinematographic style describing how the footage is captured — never as a physical object visible in the scene. Mention the style (e.g., for a probe lens: extreme close shot; for a fisheye lens: extreme wide angle fisheye view) rather than mentioning the lens or camera apparatus itself.
|
| 65 |
+
- Timelapse: If the instruction implies timelapse, explicitly use the word "timelapse" in the caption and avoid exaggerating its effects.
|
| 66 |
+
- Cuts & Montages: Always describe a single continuous shot with no hard cuts unless the user instruction explicitly used words like "cut", "hard cut", "jump cut", "shot change", or "montage". When multiple shots are requested without specifying an exact number, describe at most 3 shots, and dedicate the majority of the description to the opening action before any cut. Never use phrases like "the first shot", "the opening shot", or number shots as "first", "second", etc. — simply describe the action directly.
|
| 67 |
+
- Tone: Neutral, objective, descriptive. No opinions, value judgments, or inferred emotions unless physically observable.
|
| 68 |
+
- Length & Format: Write exactly ONE coherent paragraph of 5-8 sentences. No bullet points or lists.
|
| 69 |
+
|
| 70 |
+
USER INSTRUCTION:
|
| 71 |
+
"{nl_description}"
|
| 72 |
+
|
| 73 |
+
---
|
| 74 |
+
### PHASE 2: NEGATIVE PROMPT
|
| 75 |
+
Using your final video description from Phase 1, create a customized negative prompt.
|
| 76 |
+
|
| 77 |
+
HOW IT WORKS:
|
| 78 |
+
A negative prompt describes exactly what a bad video looks like. Use declarative statements (e.g., "blurry faces"). Never use negative instructions like "avoid" or "do not".
|
| 79 |
+
|
| 80 |
+
---
|
| 81 |
+
DEFAULT NEGATIVE PROMPT:
|
| 82 |
+
The video captures a series of frames showing macroblocking artifacts, chromatic aberration, high-frequency noise, and rolling shutter distortion. It includes static with no motion, motion blur, over-saturation, shaky footage, low resolution, grainy texture, pixelated images, poorly lit areas, underexposed and overexposed scenes, poor color balance, washed out colors, choppy sequences, jerky movements, low frame rate, bit-depth compression artifacts, color banding, unnatural transitions, outdated special effects, fake elements, unconvincing visuals, poorly edited content, jump cuts, hard cut, visual noise, and flickering. It features moiré patterns, edge halos, and temporal aliasing. Furthermore, the content defies common sense, generating illogical scenarios, nonsensical entities, absurd character behaviors, and conceptual paradoxes that violate basic human reasoning and everyday reality. The video looks like a surreal or glitchy hallucination. Overall, the video is of poor quality.
|
| 83 |
+
---
|
| 84 |
+
|
| 85 |
+
INSTRUCTIONS:
|
| 86 |
+
Delete any words from the default negative prompt that contradict your intended video. Keep most of the original wording and structure intact, and do not add new items. Examples:
|
| 87 |
+
* If you want scene cuts/montages -> REMOVE "jump cuts" and "hard cut".
|
| 88 |
+
* If you want a motionless/static scene -> REMOVE "static with no motion".
|
| 89 |
+
* If you want fantasy, sci-fi, or surrealism -> REMOVE "defies common sense", "illogical scenarios", "nonsensical entities", "surreal", and related logic-violation terms.
|
| 90 |
+
* If the scene has flickering light -> REMOVE "flickering".
|
| 91 |
+
* If it is a night-time timelapse -> REMOVE "motion blur".
|
| 92 |
+
|
| 93 |
+
Output only the final negative prompt as a single paragraph, wrapped in <negative_prompt> tags. Do not output any explanation or preamble."""
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def image_to_data_url(path: Path) -> str:
|
| 97 |
+
"""Encode a local image as a base64 data URL."""
|
| 98 |
+
mime = mimetypes.guess_type(path.name)[0] or "image/png"
|
| 99 |
+
encoded = base64.b64encode(path.read_bytes()).decode("ascii")
|
| 100 |
+
return f"data:{mime};base64,{encoded}"
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def extract_tag(text: str, tag: str) -> str | None:
|
| 104 |
+
"""Return the stripped inner text of the first <tag>...</tag> block, if present."""
|
| 105 |
+
match = re.search(rf"<{tag}>(.*?)</{tag}>", text, flags=re.DOTALL)
|
| 106 |
+
return match.group(1).strip() if match else None
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def parse_args() -> argparse.Namespace:
|
| 110 |
+
parser = argparse.ArgumentParser(description="Upsample an image-to-video prompt with a VLM.")
|
| 111 |
+
parser.add_argument("--image-path", type=Path, default=Path("assets/example_first_frame.png"))
|
| 112 |
+
parser.add_argument("--user-prompt", default="The dog flies into the outer space")
|
| 113 |
+
parser.add_argument("--output-path", type=Path, default=Path("scripts/upsampled.json"))
|
| 114 |
+
parser.add_argument("--model-name", required=True)
|
| 115 |
+
parser.add_argument("--base-url", required=True, metavar="<VLM-endpoint-url>")
|
| 116 |
+
return parser.parse_args()
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
def invoke_vlm(image_path: Path, user_prompt: str, model_name: str, base_url: str) -> str:
|
| 120 |
+
"""Call an OpenAI-compatible chat completions endpoint and return the assistant text."""
|
| 121 |
+
payload = {
|
| 122 |
+
"model": model_name,
|
| 123 |
+
"max_tokens": MAX_TOKENS,
|
| 124 |
+
"messages": [
|
| 125 |
+
{
|
| 126 |
+
"role": "user",
|
| 127 |
+
"content": [
|
| 128 |
+
{"type": "image_url", "image_url": {"url": image_to_data_url(image_path)}},
|
| 129 |
+
{"type": "text", "text": PROMPT_TEMPLATE.replace("{nl_description}", user_prompt.strip())},
|
| 130 |
+
],
|
| 131 |
+
}
|
| 132 |
+
],
|
| 133 |
+
}
|
| 134 |
+
headers = {"Authorization": f"Bearer {os.environ['PROMPT_UPSAMPLER_API_KEY']}"}
|
| 135 |
+
response = requests.post(f"{base_url.rstrip('/')}/chat/completions", json=payload, headers=headers)
|
| 136 |
+
response.raise_for_status()
|
| 137 |
+
return response.json()["choices"][0]["message"]["content"]
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
def main() -> None:
|
| 141 |
+
args = parse_args()
|
| 142 |
+
content = invoke_vlm(args.image_path, args.user_prompt, args.model_name, args.base_url)
|
| 143 |
+
|
| 144 |
+
final_prompt = extract_tag(content, "final_prompt")
|
| 145 |
+
if final_prompt is None:
|
| 146 |
+
raise RuntimeError(f"Response missing <final_prompt> block:\n{content}")
|
| 147 |
+
|
| 148 |
+
# Pin the output parameters post-hoc (the template leaves them as placeholders).
|
| 149 |
+
data = json.loads(final_prompt)
|
| 150 |
+
data["duration"] = f"{int(NUM_FRAMES / FPS)}s"
|
| 151 |
+
data["fps"] = float(round(FPS))
|
| 152 |
+
data["resolution"] = {"H": HEIGHT, "W": WIDTH}
|
| 153 |
+
data["aspect_ratio"] = ASPECT_RATIO
|
| 154 |
+
|
| 155 |
+
record: dict = {"prompt": json.dumps(data, ensure_ascii=False)}
|
| 156 |
+
negative = extract_tag(content, "negative_prompt")
|
| 157 |
+
if negative:
|
| 158 |
+
record["negative_prompt"] = negative
|
| 159 |
+
|
| 160 |
+
args.output_path.parent.mkdir(parents=True, exist_ok=True)
|
| 161 |
+
args.output_path.write_text(json.dumps(record, ensure_ascii=False), encoding="utf-8")
|
| 162 |
+
print(f"PROMPT:\n{record['prompt']}")
|
| 163 |
+
print(f"\nNEGATIVE PROMPT:\n{record.get('negative_prompt', '')}")
|
| 164 |
+
print(f"\nWrote {args.output_path}")
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
if __name__ == "__main__":
|
| 168 |
+
main()
|
serve_cosmos3_i2v4step_diffusers.py
ADDED
|
@@ -0,0 +1,449 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""
|
| 3 |
+
Local generation server for your quantized Cosmos3-Super-Image2Video-4Step, built on
|
| 4 |
+
the *validated* diffusers path (NOT vLLM-Omni). Sibling of serve_cosmos3_diffusers.py
|
| 5 |
+
(the nvidia/Cosmos3-Super base-model server) -- same build recipe, adapted for three
|
| 6 |
+
real differences in this checkpoint:
|
| 7 |
+
|
| 8 |
+
1. NO /generate (text -> still) ENDPOINT. This checkpoint is Image2Video-specific
|
| 9 |
+
(unlike the T2I/T2V/I2V-omni base model); NVIDIA's docs never demonstrate a
|
| 10 |
+
text-only call for it, and there's no local way to verify one works without
|
| 11 |
+
the checkpoint in hand. Rather than ship a silently-untested endpoint, this
|
| 12 |
+
server exposes /animate only. If a text-only path turns out to work when you
|
| 13 |
+
test it, port /generate over from serve_cosmos3_diffusers.py at that point.
|
| 14 |
+
2. NO SCHEDULER OBJECT SWAP, BUT A PATCHED set_timesteps. serve_cosmos3_diffusers.py
|
| 15 |
+
replaces the shipped scheduler with UniPCMultistepScheduler(flow_shift=...); this
|
| 16 |
+
checkpoint instead keeps FlowMatchEulerDiscreteScheduler as shipped (do not swap
|
| 17 |
+
it) but needs one targeted patch: Cosmos3OmniPipeline.__call__ always calls
|
| 18 |
+
scheduler.set_timesteps(num_inference_steps, device=device) with no passthrough
|
| 19 |
+
for this checkpoint's scheduler_config.json fixed_step_sampler_config (verified by
|
| 20 |
+
running it -- an unpatched call silently executed the pipeline's 35-step default
|
| 21 |
+
instead of the checkpoint's trained 4-step sde schedule). make_pipeline() below
|
| 22 |
+
applies _force_fixed_step_schedule() to fix this.
|
| 23 |
+
3. NO num_inference_steps IN THE REQUEST; guidance_scale IS FIXED AT 1.0. Per
|
| 24 |
+
NVIDIA's model card these are fixed by the distilled checkpoint -- CFG is
|
| 25 |
+
distilled out (do_classifier_free_guidance is guidance_scale != 1.0 in the
|
| 26 |
+
pipeline source, so the 6.0 pipeline default would silently re-enable it) and
|
| 27 |
+
the step count comes from the scheduler patch above, not from the caller.
|
| 28 |
+
|
| 29 |
+
ENDPOINTS
|
| 30 |
+
---------
|
| 31 |
+
GET /health -> readiness + which format is loaded
|
| 32 |
+
POST /animate -> image -> video (multipart upload; returns MP4, or GIF if no
|
| 33 |
+
mp4 encoder is installed)
|
| 34 |
+
|
| 35 |
+
USAGE
|
| 36 |
+
-----
|
| 37 |
+
CUDA_VISIBLE_DEVICES=0 python serve_cosmos3_i2v4step_diffusers.py --repo prometheusAIR/Cosmos3-I2V4Step-fp8
|
| 38 |
+
CUDA_VISIBLE_DEVICES=0 python serve_cosmos3_i2v4step_diffusers.py --repo ./cosmos3-i2v4step-fp8-hf
|
| 39 |
+
|
| 40 |
+
# or rebuild from the bf16 source (the original streaming path):
|
| 41 |
+
CUDA_VISIBLE_DEVICES=0 python serve_cosmos3_i2v4step_diffusers.py --format fp8
|
| 42 |
+
CUDA_VISIBLE_DEVICES=0 python serve_cosmos3_i2v4step_diffusers.py --format fp8 --cache ./cosmos3-i2v4step-cache
|
| 43 |
+
|
| 44 |
+
Image -> video:
|
| 45 |
+
curl -s -X POST http://localhost:8000/animate \
|
| 46 |
+
-F image=@out.png \
|
| 47 |
+
-F 'prompt=The robotic arm slowly lowers its gripper toward the objects and holds. Static camera.' \
|
| 48 |
+
-F num_frames=49 -F fps=24 \
|
| 49 |
+
--output clip.mp4
|
| 50 |
+
|
| 51 |
+
Health:
|
| 52 |
+
curl -s http://localhost:8000/health
|
| 53 |
+
"""
|
| 54 |
+
|
| 55 |
+
import argparse
|
| 56 |
+
import asyncio
|
| 57 |
+
import contextlib
|
| 58 |
+
import gc
|
| 59 |
+
import io
|
| 60 |
+
import os
|
| 61 |
+
import tempfile
|
| 62 |
+
|
| 63 |
+
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
|
| 64 |
+
|
| 65 |
+
import torch
|
| 66 |
+
from accelerate import init_empty_weights, load_checkpoint_in_model
|
| 67 |
+
from accelerate.utils import get_max_memory, infer_auto_device_map
|
| 68 |
+
from accelerate.utils.dataclasses import CustomDtype
|
| 69 |
+
from fastapi import FastAPI, File, Form, UploadFile
|
| 70 |
+
from fastapi.responses import Response
|
| 71 |
+
from huggingface_hub import snapshot_download
|
| 72 |
+
from PIL import Image
|
| 73 |
+
from pydantic import BaseModel
|
| 74 |
+
|
| 75 |
+
import modelopt.torch.quantization as mtq
|
| 76 |
+
from diffusers import Cosmos3OmniTransformer
|
| 77 |
+
from diffusers.utils import export_to_gif, export_to_video
|
| 78 |
+
|
| 79 |
+
SRC_REPO = "nvidia/Cosmos3-Super-Image2Video-4Step"
|
| 80 |
+
|
| 81 |
+
SPARE_SUBSTRINGS = [
|
| 82 |
+
"time_embedder", "proj_in", "proj_out", "lm_head", "embed", "norm", "audio_proj",
|
| 83 |
+
]
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def _is_spare(name: str) -> bool:
|
| 87 |
+
return any(s in name for s in SPARE_SUBSTRINGS)
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def build_quant_cfg(fmt: str) -> dict:
|
| 91 |
+
if fmt == "fp8":
|
| 92 |
+
return {
|
| 93 |
+
"quant_cfg": {
|
| 94 |
+
"*weight_quantizer": {"num_bits": (4, 3), "axis": None, "enable": True},
|
| 95 |
+
"*input_quantizer": {"enable": False},
|
| 96 |
+
"*output_quantizer": {"enable": False},
|
| 97 |
+
"*softmax_quantizer": {"enable": False},
|
| 98 |
+
},
|
| 99 |
+
"algorithm": "max",
|
| 100 |
+
}
|
| 101 |
+
if fmt == "nvfp4":
|
| 102 |
+
import copy
|
| 103 |
+
# Return the base preset UNMODIFIED -- on this installed modelopt version,
|
| 104 |
+
# W4A16_NVFP4_CFG's quant_cfg is a LIST (newer format), not the dict this
|
| 105 |
+
# function used to assume (confirmed empirically: "TypeError: list indices
|
| 106 |
+
# must be integers or slices, not str" trying dict-style key assignment
|
| 107 |
+
# here). enforce_weight_only_and_spare() below disables activations/spares
|
| 108 |
+
# on the model's actual inserted quantizer modules AFTER mtq.quantize(),
|
| 109 |
+
# which is config-form agnostic -- no need to pre-bake into the config dict.
|
| 110 |
+
# load_cosmos3_modelopt.py's loader re-applies the same disabling on every
|
| 111 |
+
# restore anyway (modelopt_state replays the config, not our imperative
|
| 112 |
+
# .disable() calls), so skipping the pre-bake here loses nothing.
|
| 113 |
+
base = getattr(mtq, "W4A16_NVFP4_CFG", None) or mtq.NVFP4_DEFAULT_CFG
|
| 114 |
+
return copy.deepcopy(base)
|
| 115 |
+
raise ValueError(f"Unknown format: {fmt!r}")
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def enforce_weight_only_and_spare(model) -> tuple[int, int]:
|
| 119 |
+
n_spare = n_act = 0
|
| 120 |
+
for name, module in model.named_modules():
|
| 121 |
+
if not (name.endswith("_quantizer") and hasattr(module, "disable")):
|
| 122 |
+
continue
|
| 123 |
+
if name.endswith("weight_quantizer"):
|
| 124 |
+
if _is_spare(name.rsplit(".", 1)[0]):
|
| 125 |
+
module.disable()
|
| 126 |
+
n_spare += 1
|
| 127 |
+
else:
|
| 128 |
+
module.disable()
|
| 129 |
+
n_act += 1
|
| 130 |
+
return n_spare, n_act
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
def compressed_device_map(model, gpu_mem_fraction: float = 0.85) -> dict:
|
| 134 |
+
max_memory = {k: v * gpu_mem_fraction for k, v in get_max_memory().items()}
|
| 135 |
+
no_split = set()
|
| 136 |
+
for name, module in model.named_modules():
|
| 137 |
+
if name.endswith((".layers.0", ".blocks.0", ".transformer_blocks.0")):
|
| 138 |
+
no_split.add(module.__class__.__name__)
|
| 139 |
+
special_dtypes = {}
|
| 140 |
+
for name, module in model.named_modules():
|
| 141 |
+
if (
|
| 142 |
+
hasattr(module, "weight")
|
| 143 |
+
and hasattr(module, "weight_quantizer")
|
| 144 |
+
and getattr(module.weight_quantizer, "is_enabled", True)
|
| 145 |
+
and not getattr(module.weight_quantizer, "fake_quant", True)
|
| 146 |
+
):
|
| 147 |
+
nb = module.weight_quantizer.num_bits
|
| 148 |
+
if isinstance(nb, tuple):
|
| 149 |
+
nb = nb[0] + nb[1] + 1
|
| 150 |
+
special_dtypes[name + ".weight"] = CustomDtype.FP8 if nb == 8 else CustomDtype.INT4
|
| 151 |
+
return infer_auto_device_map(
|
| 152 |
+
model, max_memory=max_memory,
|
| 153 |
+
no_split_module_classes=list(no_split), special_dtypes=special_dtypes,
|
| 154 |
+
)
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def _materialize_residual_meta(model) -> int:
|
| 158 |
+
n = 0
|
| 159 |
+
for _, module in model.named_modules():
|
| 160 |
+
for bn, buf in list(module._buffers.items()):
|
| 161 |
+
if buf is not None and getattr(buf, "is_meta", False):
|
| 162 |
+
module._buffers[bn] = torch.zeros(buf.shape, dtype=buf.dtype, device="cuda")
|
| 163 |
+
n += 1
|
| 164 |
+
for pn, par in list(module._parameters.items()):
|
| 165 |
+
if par is not None and getattr(par, "is_meta", False):
|
| 166 |
+
module._parameters[pn] = torch.nn.Parameter(
|
| 167 |
+
torch.zeros(par.shape, dtype=par.dtype, device="cuda"), requires_grad=False
|
| 168 |
+
)
|
| 169 |
+
n += 1
|
| 170 |
+
return n
|
| 171 |
+
|
| 172 |
+
|
| 173 |
+
def _transformer_dir() -> str:
|
| 174 |
+
local_root = snapshot_download(SRC_REPO, allow_patterns=["transformer/*"])
|
| 175 |
+
return os.path.join(local_root, "transformer")
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
def build_quantized_transformer(fmt: str, gpu_mem_fraction: float = 0.85):
|
| 179 |
+
"""The proven path: empty-on-meta -> quantize -> compress -> stream shards in."""
|
| 180 |
+
transformer_dir = _transformer_dir()
|
| 181 |
+
print(f"[build] empty transformer on meta from {transformer_dir}")
|
| 182 |
+
config = Cosmos3OmniTransformer.load_config(transformer_dir)
|
| 183 |
+
with init_empty_weights(include_buffers=False):
|
| 184 |
+
model = Cosmos3OmniTransformer.from_config(config)
|
| 185 |
+
|
| 186 |
+
print(f"[build] inserting weight-only {fmt} quantizers")
|
| 187 |
+
mtq.quantize(model, build_quant_cfg(fmt))
|
| 188 |
+
n_spare, n_act = enforce_weight_only_and_spare(model)
|
| 189 |
+
print(f"[build] weight-only: disabled {n_act} activation quantizers; {n_spare} spare weight layers")
|
| 190 |
+
|
| 191 |
+
print("[build] setting up compressed parameter shapes")
|
| 192 |
+
try:
|
| 193 |
+
mtq.compress(model, config=mtq.CompressConfig(quant_gemm=False))
|
| 194 |
+
except (AttributeError, TypeError):
|
| 195 |
+
mtq.compress(model)
|
| 196 |
+
|
| 197 |
+
print("[build] streaming BF16 shards into compressed form (slow step)")
|
| 198 |
+
load_checkpoint_in_model(
|
| 199 |
+
model, checkpoint=transformer_dir,
|
| 200 |
+
device_map=compressed_device_map(model, gpu_mem_fraction), dtype=torch.bfloat16,
|
| 201 |
+
)
|
| 202 |
+
fixed = _materialize_residual_meta(model)
|
| 203 |
+
if fixed:
|
| 204 |
+
print(f"[build] materialized {fixed} residual meta tensors")
|
| 205 |
+
return model
|
| 206 |
+
|
| 207 |
+
|
| 208 |
+
# --- optional fast-restart cache (modelopt_state + weights, per ModelOpt docs) ----------
|
| 209 |
+
def _cache_paths(cache_dir: str, fmt: str):
|
| 210 |
+
return (os.path.join(cache_dir, f"modelopt_state_{fmt}.pt"),
|
| 211 |
+
os.path.join(cache_dir, f"weights_{fmt}.pt"))
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def save_quantized(model, fmt: str, cache_dir: str) -> None:
|
| 215 |
+
try:
|
| 216 |
+
from modelopt.torch.opt import modelopt_state
|
| 217 |
+
except ImportError:
|
| 218 |
+
from modelopt.torch.opt.conversion import modelopt_state
|
| 219 |
+
os.makedirs(cache_dir, exist_ok=True)
|
| 220 |
+
state_path, weights_path = _cache_paths(cache_dir, fmt)
|
| 221 |
+
print(f"[cache] writing {state_path} + {weights_path} (large; one time)")
|
| 222 |
+
torch.save(modelopt_state(model), state_path)
|
| 223 |
+
torch.save(model.state_dict(), weights_path)
|
| 224 |
+
|
| 225 |
+
|
| 226 |
+
def try_restore_quantized(fmt: str, cache_dir: str):
|
| 227 |
+
state_path, weights_path = _cache_paths(cache_dir, fmt)
|
| 228 |
+
if not (os.path.isfile(state_path) and os.path.isfile(weights_path)):
|
| 229 |
+
return None
|
| 230 |
+
try:
|
| 231 |
+
try:
|
| 232 |
+
from modelopt.torch.opt import restore_from_modelopt_state
|
| 233 |
+
except ImportError:
|
| 234 |
+
from modelopt.torch.opt.conversion import restore_from_modelopt_state
|
| 235 |
+
print(f"[cache] restoring from {state_path}")
|
| 236 |
+
config = Cosmos3OmniTransformer.load_config(_transformer_dir())
|
| 237 |
+
with init_empty_weights(include_buffers=False):
|
| 238 |
+
model = Cosmos3OmniTransformer.from_config(config)
|
| 239 |
+
state = torch.load(state_path, map_location="cpu", weights_only=False)
|
| 240 |
+
restore_from_modelopt_state(model, state)
|
| 241 |
+
weights = torch.load(weights_path, map_location="cpu", weights_only=False)
|
| 242 |
+
model.load_state_dict(weights, strict=False, assign=True)
|
| 243 |
+
_materialize_residual_meta(model)
|
| 244 |
+
print("[cache] restore OK")
|
| 245 |
+
return model
|
| 246 |
+
except Exception as e:
|
| 247 |
+
import traceback
|
| 248 |
+
print(f"[cache] restore failed ({type(e).__name__}: {e}); falling back to full rebuild")
|
| 249 |
+
traceback.print_exc()
|
| 250 |
+
return None
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
def _force_fixed_step_schedule(scheduler) -> bool:
|
| 254 |
+
"""See module docstring point 2. Patches THIS scheduler instance's set_timesteps
|
| 255 |
+
to always use the checkpoint's own fixed_step_sampler_config.t_list, regardless of
|
| 256 |
+
whatever num_inference_steps Cosmos3OmniPipeline.__call__ passes in internally.
|
| 257 |
+
|
| 258 |
+
ALSO disables stochastic_sampling (forces the deterministic ODE branch) -- CONFIRMED
|
| 259 |
+
by direct A/B render (same seed/image/prompt), not speculative. This checkpoint's
|
| 260 |
+
scheduler ships stochastic_sampling=True (SDE). Cosmos3's image-conditioning anchors
|
| 261 |
+
frame 0 by zeroing the model's predicted velocity there; that only means "leave this
|
| 262 |
+
position unchanged" under the deterministic step (prev_sample = sample + dt*0). The
|
| 263 |
+
SDE branch instead computes x0 = sample - current_sigma*model_output (= sample when
|
| 264 |
+
velocity is 0), then prev_sample = (1-next_sigma)*x0 + next_sigma*randn_tensor(...) --
|
| 265 |
+
it re-noises by next_sigma regardless of velocity, with no zero-velocity no-op. Over
|
| 266 |
+
this checkpoint's 4 steps that compounds to ~99.6% fresh noise in the conditioned
|
| 267 |
+
frame by the end: the input image comes out as colorful static while the genuinely
|
| 268 |
+
denoised motion frames still look like a plausible video. Disabling stochastic_
|
| 269 |
+
sampling restores the correct zero-velocity-is-a-no-op behavior."""
|
| 270 |
+
cfg = getattr(scheduler.config, "fixed_step_sampler_config", None)
|
| 271 |
+
t_list = cfg.get("t_list") if isinstance(cfg, dict) else None
|
| 272 |
+
if not t_list:
|
| 273 |
+
print("[warn] no fixed_step_sampler_config.t_list on this scheduler; leaving set_timesteps unpatched")
|
| 274 |
+
return False
|
| 275 |
+
_orig = scheduler.set_timesteps
|
| 276 |
+
|
| 277 |
+
def _patched(num_inference_steps=None, device=None, sigmas=None, mu=None, timesteps=None):
|
| 278 |
+
return _orig(sigmas=list(t_list), device=device)
|
| 279 |
+
|
| 280 |
+
scheduler.set_timesteps = _patched
|
| 281 |
+
if getattr(scheduler.config, "stochastic_sampling", False):
|
| 282 |
+
scheduler.register_to_config(stochastic_sampling=False)
|
| 283 |
+
print("[build] disabled stochastic_sampling (SDE re-noising corrupts the "
|
| 284 |
+
"image-conditioned frame -- see docstring)")
|
| 285 |
+
print(f"[build] forced fixed {len(t_list)}-step sde schedule: {t_list}")
|
| 286 |
+
return True
|
| 287 |
+
|
| 288 |
+
|
| 289 |
+
# --- pipeline assembly --------------------------------------------------------------
|
| 290 |
+
def make_pipeline(model):
|
| 291 |
+
from diffusers import Cosmos3OmniPipeline
|
| 292 |
+
|
| 293 |
+
model.to("cuda")
|
| 294 |
+
for m in model.modules():
|
| 295 |
+
for bn, buf in list(m._buffers.items()):
|
| 296 |
+
if buf is not None and buf.dtype == torch.float32:
|
| 297 |
+
m._buffers[bn] = buf.to(torch.bfloat16)
|
| 298 |
+
|
| 299 |
+
def _cast_bf16(_m, args):
|
| 300 |
+
return tuple(
|
| 301 |
+
a.to(torch.bfloat16)
|
| 302 |
+
if torch.is_tensor(a) and a.is_floating_point() and a.dtype != torch.bfloat16 else a
|
| 303 |
+
for a in args
|
| 304 |
+
)
|
| 305 |
+
|
| 306 |
+
for name, m in model.named_modules():
|
| 307 |
+
if "time_embedder" in name and hasattr(m, "linear_1"):
|
| 308 |
+
m.register_forward_pre_hook(_cast_bf16)
|
| 309 |
+
|
| 310 |
+
pipe = Cosmos3OmniPipeline.from_pretrained(
|
| 311 |
+
SRC_REPO, transformer=model, torch_dtype=torch.bfloat16,
|
| 312 |
+
enable_safety_checker=False, # local single-user server; revisit if exposing it
|
| 313 |
+
)
|
| 314 |
+
# Keep the shipped FlowMatchEulerDiscreteScheduler object, but patch its
|
| 315 |
+
# set_timesteps to actually honor the checkpoint's fixed 4-step sde schedule.
|
| 316 |
+
_force_fixed_step_schedule(pipe.scheduler)
|
| 317 |
+
for name, comp in pipe.components.items():
|
| 318 |
+
if name != "transformer" and isinstance(comp, torch.nn.Module):
|
| 319 |
+
comp.to("cuda")
|
| 320 |
+
return pipe
|
| 321 |
+
|
| 322 |
+
|
| 323 |
+
# --- HTTP server ------------------------------------------------------------------------
|
| 324 |
+
STATE: dict = {}
|
| 325 |
+
_gen_lock = asyncio.Lock() # one generation at a time on a single GPU
|
| 326 |
+
|
| 327 |
+
|
| 328 |
+
def _run_i2v(pil_image, prompt, negative_prompt, num_frames, fps, height, width, seed) -> tuple[bytes, str]:
|
| 329 |
+
pipe = STATE["pipe"]
|
| 330 |
+
image = pil_image.convert("RGB") # the pipeline resizes this to (height, width)
|
| 331 |
+
gen = torch.Generator(device="cuda").manual_seed(int(seed)) if seed >= 0 else None
|
| 332 |
+
with torch.inference_mode():
|
| 333 |
+
# num_inference_steps is a no-op once _force_fixed_step_schedule has patched
|
| 334 |
+
# the scheduler (it always substitutes the checkpoint's own t_list).
|
| 335 |
+
# guidance_scale=1.0 disables CFG -- see module docstring point 3.
|
| 336 |
+
result = pipe(
|
| 337 |
+
prompt=prompt, negative_prompt=negative_prompt,
|
| 338 |
+
image=image, num_frames=num_frames, fps=fps,
|
| 339 |
+
height=height, width=width,
|
| 340 |
+
num_inference_steps=4, guidance_scale=1.0,
|
| 341 |
+
generator=gen, output_type="pil",
|
| 342 |
+
)
|
| 343 |
+
frames = result.video
|
| 344 |
+
try:
|
| 345 |
+
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tf:
|
| 346 |
+
path = tf.name
|
| 347 |
+
export_to_video(frames, path, fps=int(round(fps)))
|
| 348 |
+
media = "video/mp4"
|
| 349 |
+
except Exception: # no mp4 backend installed -> GIF (PIL-only, always works)
|
| 350 |
+
with tempfile.NamedTemporaryFile(suffix=".gif", delete=False) as tf:
|
| 351 |
+
path = tf.name
|
| 352 |
+
export_to_gif(frames, path)
|
| 353 |
+
media = "image/gif"
|
| 354 |
+
data = open(path, "rb").read()
|
| 355 |
+
os.remove(path)
|
| 356 |
+
del result
|
| 357 |
+
gc.collect()
|
| 358 |
+
torch.cuda.empty_cache()
|
| 359 |
+
return data, media
|
| 360 |
+
|
| 361 |
+
|
| 362 |
+
@contextlib.asynccontextmanager
|
| 363 |
+
async def lifespan(app: FastAPI):
|
| 364 |
+
fmt = STATE["fmt"]
|
| 365 |
+
repo = STATE.get("repo")
|
| 366 |
+
if repo:
|
| 367 |
+
from load_cosmos3_modelopt import load_pipe
|
| 368 |
+
|
| 369 |
+
path = repo
|
| 370 |
+
if not os.path.isdir(path):
|
| 371 |
+
from huggingface_hub import snapshot_download as _snap
|
| 372 |
+
print(f"[serve] fetching full snapshot of {repo} from the Hub ...")
|
| 373 |
+
path = _snap(repo)
|
| 374 |
+
print(f"[serve] loading drop-in checkpoint: {path}")
|
| 375 |
+
pipe = load_pipe(path)
|
| 376 |
+
# load_cosmos3_modelopt.load_pipe() is shared with the base model and doesn't
|
| 377 |
+
# know about this checkpoint's fixed-step schedule -- patch it here instead.
|
| 378 |
+
_force_fixed_step_schedule(pipe.scheduler)
|
| 379 |
+
STATE["pipe"] = pipe
|
| 380 |
+
print(f"[serve] ready (drop-in: {repo}, {fmt.upper()} assumed from repo contents)")
|
| 381 |
+
yield
|
| 382 |
+
STATE.clear()
|
| 383 |
+
return
|
| 384 |
+
cache_dir = STATE.get("cache_dir")
|
| 385 |
+
model = None
|
| 386 |
+
if cache_dir:
|
| 387 |
+
model = try_restore_quantized(fmt, cache_dir)
|
| 388 |
+
if model is None:
|
| 389 |
+
model = build_quantized_transformer(fmt, STATE["gpu_mem_fraction"])
|
| 390 |
+
if cache_dir:
|
| 391 |
+
try:
|
| 392 |
+
save_quantized(model, fmt, cache_dir)
|
| 393 |
+
except Exception as e:
|
| 394 |
+
print(f"[cache] save failed ({type(e).__name__}: {e}); continuing without cache")
|
| 395 |
+
STATE["pipe"] = make_pipeline(model)
|
| 396 |
+
print(f"[ready] serving {fmt.upper()} Cosmos3-Super-Image2Video-4Step on diffusers")
|
| 397 |
+
yield
|
| 398 |
+
STATE.clear()
|
| 399 |
+
|
| 400 |
+
|
| 401 |
+
app = FastAPI(lifespan=lifespan)
|
| 402 |
+
|
| 403 |
+
|
| 404 |
+
@app.get("/health")
|
| 405 |
+
async def health():
|
| 406 |
+
return {"status": "ok" if "pipe" in STATE else "loading", "format": STATE.get("fmt")}
|
| 407 |
+
|
| 408 |
+
|
| 409 |
+
@app.post("/animate")
|
| 410 |
+
async def animate(
|
| 411 |
+
image: UploadFile = File(...),
|
| 412 |
+
prompt: str = Form(...),
|
| 413 |
+
negative_prompt: str = Form(""),
|
| 414 |
+
num_frames: int = Form(49), # ~2.04s @ 24fps; 4n+1 maps cleanly to the VAE's 4x temporal compression
|
| 415 |
+
fps: float = Form(24.0),
|
| 416 |
+
height: int = Form(1024),
|
| 417 |
+
width: int = Form(1024),
|
| 418 |
+
seed: int = Form(1234), # pass -1 for a random clip each call
|
| 419 |
+
):
|
| 420 |
+
pil = Image.open(io.BytesIO(await image.read()))
|
| 421 |
+
async with _gen_lock:
|
| 422 |
+
loop = asyncio.get_running_loop()
|
| 423 |
+
data, media = await loop.run_in_executor(
|
| 424 |
+
None, _run_i2v, pil, prompt, negative_prompt, num_frames, fps, height, width, seed,
|
| 425 |
+
)
|
| 426 |
+
return Response(content=data, media_type=media)
|
| 427 |
+
|
| 428 |
+
|
| 429 |
+
if __name__ == "__main__":
|
| 430 |
+
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
| 431 |
+
ap.add_argument("--format", choices=["fp8", "nvfp4"], default="fp8")
|
| 432 |
+
ap.add_argument("--repo", default=None,
|
| 433 |
+
help="Serve a published drop-in checkpoint: an HF repo id or a local "
|
| 434 |
+
"repackaged dir. Skips the bf16 rebuild entirely; requires "
|
| 435 |
+
"load_cosmos3_modelopt.py next to this file.")
|
| 436 |
+
ap.add_argument("--host", default="0.0.0.0")
|
| 437 |
+
ap.add_argument("--port", type=int, default=8000)
|
| 438 |
+
ap.add_argument("--gpu-mem-fraction", type=float, default=0.85)
|
| 439 |
+
ap.add_argument("--cache", default=None,
|
| 440 |
+
help="Dir for a fast-restart cache. First boot rebuilds + writes it; "
|
| 441 |
+
"later boots restore from it. Any restore error -> full rebuild.")
|
| 442 |
+
args = ap.parse_args()
|
| 443 |
+
|
| 444 |
+
STATE.update(
|
| 445 |
+
fmt=args.format, gpu_mem_fraction=args.gpu_mem_fraction, cache_dir=args.cache, repo=args.repo,
|
| 446 |
+
)
|
| 447 |
+
|
| 448 |
+
import uvicorn
|
| 449 |
+
uvicorn.run(app, host=args.host, port=args.port)
|
text_tokenizer/added_tokens.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"</think>": 151668,
|
| 3 |
+
"</tool_call>": 151658,
|
| 4 |
+
"</tool_response>": 151666,
|
| 5 |
+
"<think>": 151667,
|
| 6 |
+
"<tool_call>": 151657,
|
| 7 |
+
"<tool_response>": 151665,
|
| 8 |
+
"<|box_end|>": 151649,
|
| 9 |
+
"<|box_start|>": 151648,
|
| 10 |
+
"<|endoftext|>": 151643,
|
| 11 |
+
"<|file_sep|>": 151664,
|
| 12 |
+
"<|fim_middle|>": 151660,
|
| 13 |
+
"<|fim_pad|>": 151662,
|
| 14 |
+
"<|fim_prefix|>": 151659,
|
| 15 |
+
"<|fim_suffix|>": 151661,
|
| 16 |
+
"<|im_end|>": 151645,
|
| 17 |
+
"<|im_start|>": 151644,
|
| 18 |
+
"<|image_pad|>": 151655,
|
| 19 |
+
"<|object_ref_end|>": 151647,
|
| 20 |
+
"<|object_ref_start|>": 151646,
|
| 21 |
+
"<|quad_end|>": 151651,
|
| 22 |
+
"<|quad_start|>": 151650,
|
| 23 |
+
"<|repo_name|>": 151663,
|
| 24 |
+
"<|video_pad|>": 151656,
|
| 25 |
+
"<|vision_end|>": 151653,
|
| 26 |
+
"<|vision_pad|>": 151654,
|
| 27 |
+
"<|vision_start|>": 151652
|
| 28 |
+
}
|
text_tokenizer/chat_template.jinja
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- if tools %}
|
| 2 |
+
{{- '<|im_start|>system\n' }}
|
| 3 |
+
{%- if messages[0].role == 'system' %}
|
| 4 |
+
{%- if messages[0].content is string %}
|
| 5 |
+
{{- messages[0].content }}
|
| 6 |
+
{%- else %}
|
| 7 |
+
{%- for content in messages[0].content %}
|
| 8 |
+
{%- if 'text' in content %}
|
| 9 |
+
{{- content.text }}
|
| 10 |
+
{%- endif %}
|
| 11 |
+
{%- endfor %}
|
| 12 |
+
{%- endif %}
|
| 13 |
+
{{- '\n\n' }}
|
| 14 |
+
{%- endif %}
|
| 15 |
+
{{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
|
| 16 |
+
{%- for tool in tools %}
|
| 17 |
+
{{- "\n" }}
|
| 18 |
+
{{- tool | tojson }}
|
| 19 |
+
{%- endfor %}
|
| 20 |
+
{{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
|
| 21 |
+
{%- else %}
|
| 22 |
+
{%- if messages[0].role == 'system' %}
|
| 23 |
+
{{- '<|im_start|>system\n' }}
|
| 24 |
+
{%- if messages[0].content is string %}
|
| 25 |
+
{{- messages[0].content }}
|
| 26 |
+
{%- else %}
|
| 27 |
+
{%- for content in messages[0].content %}
|
| 28 |
+
{%- if 'text' in content %}
|
| 29 |
+
{{- content.text }}
|
| 30 |
+
{%- endif %}
|
| 31 |
+
{%- endfor %}
|
| 32 |
+
{%- endif %}
|
| 33 |
+
{{- '<|im_end|>\n' }}
|
| 34 |
+
{%- endif %}
|
| 35 |
+
{%- endif %}
|
| 36 |
+
{%- set image_count = namespace(value=0) %}
|
| 37 |
+
{%- set video_count = namespace(value=0) %}
|
| 38 |
+
{%- for message in messages %}
|
| 39 |
+
{%- if message.role == "user" %}
|
| 40 |
+
{{- '<|im_start|>' + message.role + '\n' }}
|
| 41 |
+
{%- if message.content is string %}
|
| 42 |
+
{{- message.content }}
|
| 43 |
+
{%- else %}
|
| 44 |
+
{%- for content in message.content %}
|
| 45 |
+
{%- if content.type == 'image' or 'image' in content or 'image_url' in content %}
|
| 46 |
+
{%- set image_count.value = image_count.value + 1 %}
|
| 47 |
+
{%- if add_vision_id %}Picture {{ image_count.value }}: {% endif -%}
|
| 48 |
+
<|vision_start|><|image_pad|><|vision_end|>
|
| 49 |
+
{%- elif content.type == 'video' or 'video' in content %}
|
| 50 |
+
{%- set video_count.value = video_count.value + 1 %}
|
| 51 |
+
{%- if add_vision_id %}Video {{ video_count.value }}: {% endif -%}
|
| 52 |
+
<|vision_start|><|video_pad|><|vision_end|>
|
| 53 |
+
{%- elif 'text' in content %}
|
| 54 |
+
{{- content.text }}
|
| 55 |
+
{%- endif %}
|
| 56 |
+
{%- endfor %}
|
| 57 |
+
{%- endif %}
|
| 58 |
+
{{- '<|im_end|>\n' }}
|
| 59 |
+
{%- elif message.role == "assistant" %}
|
| 60 |
+
{{- '<|im_start|>' + message.role + '\n' }}
|
| 61 |
+
{%- if message.content is string %}
|
| 62 |
+
{{- message.content }}
|
| 63 |
+
{%- else %}
|
| 64 |
+
{%- for content_item in message.content %}
|
| 65 |
+
{%- if 'text' in content_item %}
|
| 66 |
+
{{- content_item.text }}
|
| 67 |
+
{%- endif %}
|
| 68 |
+
{%- endfor %}
|
| 69 |
+
{%- endif %}
|
| 70 |
+
{%- if message.tool_calls %}
|
| 71 |
+
{%- for tool_call in message.tool_calls %}
|
| 72 |
+
{%- if (loop.first and message.content) or (not loop.first) %}
|
| 73 |
+
{{- '\n' }}
|
| 74 |
+
{%- endif %}
|
| 75 |
+
{%- if tool_call.function %}
|
| 76 |
+
{%- set tool_call = tool_call.function %}
|
| 77 |
+
{%- endif %}
|
| 78 |
+
{{- '<tool_call>\n{"name": "' }}
|
| 79 |
+
{{- tool_call.name }}
|
| 80 |
+
{{- '", "arguments": ' }}
|
| 81 |
+
{%- if tool_call.arguments is string %}
|
| 82 |
+
{{- tool_call.arguments }}
|
| 83 |
+
{%- else %}
|
| 84 |
+
{{- tool_call.arguments | tojson }}
|
| 85 |
+
{%- endif %}
|
| 86 |
+
{{- '}\n</tool_call>' }}
|
| 87 |
+
{%- endfor %}
|
| 88 |
+
{%- endif %}
|
| 89 |
+
{{- '<|im_end|>\n' }}
|
| 90 |
+
{%- elif message.role == "tool" %}
|
| 91 |
+
{%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
|
| 92 |
+
{{- '<|im_start|>user' }}
|
| 93 |
+
{%- endif %}
|
| 94 |
+
{{- '\n<tool_response>\n' }}
|
| 95 |
+
{%- if message.content is string %}
|
| 96 |
+
{{- message.content }}
|
| 97 |
+
{%- else %}
|
| 98 |
+
{%- for content in message.content %}
|
| 99 |
+
{%- if content.type == 'image' or 'image' in content or 'image_url' in content %}
|
| 100 |
+
{%- set image_count.value = image_count.value + 1 %}
|
| 101 |
+
{%- if add_vision_id %}Picture {{ image_count.value }}: {% endif -%}
|
| 102 |
+
<|vision_start|><|image_pad|><|vision_end|>
|
| 103 |
+
{%- elif content.type == 'video' or 'video' in content %}
|
| 104 |
+
{%- set video_count.value = video_count.value + 1 %}
|
| 105 |
+
{%- if add_vision_id %}Video {{ video_count.value }}: {% endif -%}
|
| 106 |
+
<|vision_start|><|video_pad|><|vision_end|>
|
| 107 |
+
{%- elif 'text' in content %}
|
| 108 |
+
{{- content.text }}
|
| 109 |
+
{%- endif %}
|
| 110 |
+
{%- endfor %}
|
| 111 |
+
{%- endif %}
|
| 112 |
+
{{- '\n</tool_response>' }}
|
| 113 |
+
{%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
|
| 114 |
+
{{- '<|im_end|>\n' }}
|
| 115 |
+
{%- endif %}
|
| 116 |
+
{%- endif %}
|
| 117 |
+
{%- endfor %}
|
| 118 |
+
{%- if add_generation_prompt %}
|
| 119 |
+
{{- '<|im_start|>assistant\n' }}
|
| 120 |
+
{%- endif %}
|
text_tokenizer/merges.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
text_tokenizer/special_tokens_map.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"additional_special_tokens": [
|
| 3 |
+
"<|im_start|>",
|
| 4 |
+
"<|im_end|>",
|
| 5 |
+
"<|object_ref_start|>",
|
| 6 |
+
"<|object_ref_end|>",
|
| 7 |
+
"<|box_start|>",
|
| 8 |
+
"<|box_end|>",
|
| 9 |
+
"<|quad_start|>",
|
| 10 |
+
"<|quad_end|>",
|
| 11 |
+
"<|vision_start|>",
|
| 12 |
+
"<|vision_end|>",
|
| 13 |
+
"<|vision_pad|>",
|
| 14 |
+
"<|image_pad|>",
|
| 15 |
+
"<|video_pad|>"
|
| 16 |
+
],
|
| 17 |
+
"eos_token": {
|
| 18 |
+
"content": "<|im_end|>",
|
| 19 |
+
"lstrip": false,
|
| 20 |
+
"normalized": false,
|
| 21 |
+
"rstrip": false,
|
| 22 |
+
"single_word": false
|
| 23 |
+
},
|
| 24 |
+
"pad_token": {
|
| 25 |
+
"content": "<|endoftext|>",
|
| 26 |
+
"lstrip": false,
|
| 27 |
+
"normalized": false,
|
| 28 |
+
"rstrip": false,
|
| 29 |
+
"single_word": false
|
| 30 |
+
}
|
| 31 |
+
}
|
text_tokenizer/tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:aeb13307a71acd8fe81861d94ad54ab689df773318809eed3cbe794b4492dae4
|
| 3 |
+
size 11422654
|
text_tokenizer/tokenizer_config.json
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_bos_token": false,
|
| 3 |
+
"add_prefix_space": false,
|
| 4 |
+
"added_tokens_decoder": {
|
| 5 |
+
"151643": {
|
| 6 |
+
"content": "<|endoftext|>",
|
| 7 |
+
"lstrip": false,
|
| 8 |
+
"normalized": false,
|
| 9 |
+
"rstrip": false,
|
| 10 |
+
"single_word": false,
|
| 11 |
+
"special": true
|
| 12 |
+
},
|
| 13 |
+
"151644": {
|
| 14 |
+
"content": "<|im_start|>",
|
| 15 |
+
"lstrip": false,
|
| 16 |
+
"normalized": false,
|
| 17 |
+
"rstrip": false,
|
| 18 |
+
"single_word": false,
|
| 19 |
+
"special": true
|
| 20 |
+
},
|
| 21 |
+
"151645": {
|
| 22 |
+
"content": "<|im_end|>",
|
| 23 |
+
"lstrip": false,
|
| 24 |
+
"normalized": false,
|
| 25 |
+
"rstrip": false,
|
| 26 |
+
"single_word": false,
|
| 27 |
+
"special": true
|
| 28 |
+
},
|
| 29 |
+
"151646": {
|
| 30 |
+
"content": "<|object_ref_start|>",
|
| 31 |
+
"lstrip": false,
|
| 32 |
+
"normalized": false,
|
| 33 |
+
"rstrip": false,
|
| 34 |
+
"single_word": false,
|
| 35 |
+
"special": true
|
| 36 |
+
},
|
| 37 |
+
"151647": {
|
| 38 |
+
"content": "<|object_ref_end|>",
|
| 39 |
+
"lstrip": false,
|
| 40 |
+
"normalized": false,
|
| 41 |
+
"rstrip": false,
|
| 42 |
+
"single_word": false,
|
| 43 |
+
"special": true
|
| 44 |
+
},
|
| 45 |
+
"151648": {
|
| 46 |
+
"content": "<|box_start|>",
|
| 47 |
+
"lstrip": false,
|
| 48 |
+
"normalized": false,
|
| 49 |
+
"rstrip": false,
|
| 50 |
+
"single_word": false,
|
| 51 |
+
"special": true
|
| 52 |
+
},
|
| 53 |
+
"151649": {
|
| 54 |
+
"content": "<|box_end|>",
|
| 55 |
+
"lstrip": false,
|
| 56 |
+
"normalized": false,
|
| 57 |
+
"rstrip": false,
|
| 58 |
+
"single_word": false,
|
| 59 |
+
"special": true
|
| 60 |
+
},
|
| 61 |
+
"151650": {
|
| 62 |
+
"content": "<|quad_start|>",
|
| 63 |
+
"lstrip": false,
|
| 64 |
+
"normalized": false,
|
| 65 |
+
"rstrip": false,
|
| 66 |
+
"single_word": false,
|
| 67 |
+
"special": true
|
| 68 |
+
},
|
| 69 |
+
"151651": {
|
| 70 |
+
"content": "<|quad_end|>",
|
| 71 |
+
"lstrip": false,
|
| 72 |
+
"normalized": false,
|
| 73 |
+
"rstrip": false,
|
| 74 |
+
"single_word": false,
|
| 75 |
+
"special": true
|
| 76 |
+
},
|
| 77 |
+
"151652": {
|
| 78 |
+
"content": "<|vision_start|>",
|
| 79 |
+
"lstrip": false,
|
| 80 |
+
"normalized": false,
|
| 81 |
+
"rstrip": false,
|
| 82 |
+
"single_word": false,
|
| 83 |
+
"special": true
|
| 84 |
+
},
|
| 85 |
+
"151653": {
|
| 86 |
+
"content": "<|vision_end|>",
|
| 87 |
+
"lstrip": false,
|
| 88 |
+
"normalized": false,
|
| 89 |
+
"rstrip": false,
|
| 90 |
+
"single_word": false,
|
| 91 |
+
"special": true
|
| 92 |
+
},
|
| 93 |
+
"151654": {
|
| 94 |
+
"content": "<|vision_pad|>",
|
| 95 |
+
"lstrip": false,
|
| 96 |
+
"normalized": false,
|
| 97 |
+
"rstrip": false,
|
| 98 |
+
"single_word": false,
|
| 99 |
+
"special": true
|
| 100 |
+
},
|
| 101 |
+
"151655": {
|
| 102 |
+
"content": "<|image_pad|>",
|
| 103 |
+
"lstrip": false,
|
| 104 |
+
"normalized": false,
|
| 105 |
+
"rstrip": false,
|
| 106 |
+
"single_word": false,
|
| 107 |
+
"special": true
|
| 108 |
+
},
|
| 109 |
+
"151656": {
|
| 110 |
+
"content": "<|video_pad|>",
|
| 111 |
+
"lstrip": false,
|
| 112 |
+
"normalized": false,
|
| 113 |
+
"rstrip": false,
|
| 114 |
+
"single_word": false,
|
| 115 |
+
"special": true
|
| 116 |
+
},
|
| 117 |
+
"151657": {
|
| 118 |
+
"content": "<tool_call>",
|
| 119 |
+
"lstrip": false,
|
| 120 |
+
"normalized": false,
|
| 121 |
+
"rstrip": false,
|
| 122 |
+
"single_word": false,
|
| 123 |
+
"special": false
|
| 124 |
+
},
|
| 125 |
+
"151658": {
|
| 126 |
+
"content": "</tool_call>",
|
| 127 |
+
"lstrip": false,
|
| 128 |
+
"normalized": false,
|
| 129 |
+
"rstrip": false,
|
| 130 |
+
"single_word": false,
|
| 131 |
+
"special": false
|
| 132 |
+
},
|
| 133 |
+
"151659": {
|
| 134 |
+
"content": "<|fim_prefix|>",
|
| 135 |
+
"lstrip": false,
|
| 136 |
+
"normalized": false,
|
| 137 |
+
"rstrip": false,
|
| 138 |
+
"single_word": false,
|
| 139 |
+
"special": false
|
| 140 |
+
},
|
| 141 |
+
"151660": {
|
| 142 |
+
"content": "<|fim_middle|>",
|
| 143 |
+
"lstrip": false,
|
| 144 |
+
"normalized": false,
|
| 145 |
+
"rstrip": false,
|
| 146 |
+
"single_word": false,
|
| 147 |
+
"special": false
|
| 148 |
+
},
|
| 149 |
+
"151661": {
|
| 150 |
+
"content": "<|fim_suffix|>",
|
| 151 |
+
"lstrip": false,
|
| 152 |
+
"normalized": false,
|
| 153 |
+
"rstrip": false,
|
| 154 |
+
"single_word": false,
|
| 155 |
+
"special": false
|
| 156 |
+
},
|
| 157 |
+
"151662": {
|
| 158 |
+
"content": "<|fim_pad|>",
|
| 159 |
+
"lstrip": false,
|
| 160 |
+
"normalized": false,
|
| 161 |
+
"rstrip": false,
|
| 162 |
+
"single_word": false,
|
| 163 |
+
"special": false
|
| 164 |
+
},
|
| 165 |
+
"151663": {
|
| 166 |
+
"content": "<|repo_name|>",
|
| 167 |
+
"lstrip": false,
|
| 168 |
+
"normalized": false,
|
| 169 |
+
"rstrip": false,
|
| 170 |
+
"single_word": false,
|
| 171 |
+
"special": false
|
| 172 |
+
},
|
| 173 |
+
"151664": {
|
| 174 |
+
"content": "<|file_sep|>",
|
| 175 |
+
"lstrip": false,
|
| 176 |
+
"normalized": false,
|
| 177 |
+
"rstrip": false,
|
| 178 |
+
"single_word": false,
|
| 179 |
+
"special": false
|
| 180 |
+
},
|
| 181 |
+
"151665": {
|
| 182 |
+
"content": "<tool_response>",
|
| 183 |
+
"lstrip": false,
|
| 184 |
+
"normalized": false,
|
| 185 |
+
"rstrip": false,
|
| 186 |
+
"single_word": false,
|
| 187 |
+
"special": false
|
| 188 |
+
},
|
| 189 |
+
"151666": {
|
| 190 |
+
"content": "</tool_response>",
|
| 191 |
+
"lstrip": false,
|
| 192 |
+
"normalized": false,
|
| 193 |
+
"rstrip": false,
|
| 194 |
+
"single_word": false,
|
| 195 |
+
"special": false
|
| 196 |
+
},
|
| 197 |
+
"151667": {
|
| 198 |
+
"content": "<think>",
|
| 199 |
+
"lstrip": false,
|
| 200 |
+
"normalized": false,
|
| 201 |
+
"rstrip": false,
|
| 202 |
+
"single_word": false,
|
| 203 |
+
"special": false
|
| 204 |
+
},
|
| 205 |
+
"151668": {
|
| 206 |
+
"content": "</think>",
|
| 207 |
+
"lstrip": false,
|
| 208 |
+
"normalized": false,
|
| 209 |
+
"rstrip": false,
|
| 210 |
+
"single_word": false,
|
| 211 |
+
"special": false
|
| 212 |
+
}
|
| 213 |
+
},
|
| 214 |
+
"additional_special_tokens": [
|
| 215 |
+
"<|im_start|>",
|
| 216 |
+
"<|im_end|>",
|
| 217 |
+
"<|object_ref_start|>",
|
| 218 |
+
"<|object_ref_end|>",
|
| 219 |
+
"<|box_start|>",
|
| 220 |
+
"<|box_end|>",
|
| 221 |
+
"<|quad_start|>",
|
| 222 |
+
"<|quad_end|>",
|
| 223 |
+
"<|vision_start|>",
|
| 224 |
+
"<|vision_end|>",
|
| 225 |
+
"<|vision_pad|>",
|
| 226 |
+
"<|image_pad|>",
|
| 227 |
+
"<|video_pad|>"
|
| 228 |
+
],
|
| 229 |
+
"bos_token": null,
|
| 230 |
+
"clean_up_tokenization_spaces": false,
|
| 231 |
+
"eos_token": "<|im_end|>",
|
| 232 |
+
"errors": "replace",
|
| 233 |
+
"extra_special_tokens": {},
|
| 234 |
+
"model_max_length": 262144,
|
| 235 |
+
"pad_token": "<|endoftext|>",
|
| 236 |
+
"split_special_tokens": false,
|
| 237 |
+
"tokenizer_class": "Qwen2Tokenizer",
|
| 238 |
+
"unk_token": null
|
| 239 |
+
}
|
text_tokenizer/vocab.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
tokenizer.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_bos_token": false,
|
| 3 |
+
"add_prefix_space": false,
|
| 4 |
+
"added_tokens_decoder": {
|
| 5 |
+
"151643": {
|
| 6 |
+
"content": "<|endoftext|>",
|
| 7 |
+
"lstrip": false,
|
| 8 |
+
"normalized": false,
|
| 9 |
+
"rstrip": false,
|
| 10 |
+
"single_word": false,
|
| 11 |
+
"special": true
|
| 12 |
+
},
|
| 13 |
+
"151644": {
|
| 14 |
+
"content": "<|im_start|>",
|
| 15 |
+
"lstrip": false,
|
| 16 |
+
"normalized": false,
|
| 17 |
+
"rstrip": false,
|
| 18 |
+
"single_word": false,
|
| 19 |
+
"special": true
|
| 20 |
+
},
|
| 21 |
+
"151645": {
|
| 22 |
+
"content": "<|im_end|>",
|
| 23 |
+
"lstrip": false,
|
| 24 |
+
"normalized": false,
|
| 25 |
+
"rstrip": false,
|
| 26 |
+
"single_word": false,
|
| 27 |
+
"special": true
|
| 28 |
+
},
|
| 29 |
+
"151646": {
|
| 30 |
+
"content": "<|object_ref_start|>",
|
| 31 |
+
"lstrip": false,
|
| 32 |
+
"normalized": false,
|
| 33 |
+
"rstrip": false,
|
| 34 |
+
"single_word": false,
|
| 35 |
+
"special": true
|
| 36 |
+
},
|
| 37 |
+
"151647": {
|
| 38 |
+
"content": "<|object_ref_end|>",
|
| 39 |
+
"lstrip": false,
|
| 40 |
+
"normalized": false,
|
| 41 |
+
"rstrip": false,
|
| 42 |
+
"single_word": false,
|
| 43 |
+
"special": true
|
| 44 |
+
},
|
| 45 |
+
"151648": {
|
| 46 |
+
"content": "<|box_start|>",
|
| 47 |
+
"lstrip": false,
|
| 48 |
+
"normalized": false,
|
| 49 |
+
"rstrip": false,
|
| 50 |
+
"single_word": false,
|
| 51 |
+
"special": true
|
| 52 |
+
},
|
| 53 |
+
"151649": {
|
| 54 |
+
"content": "<|box_end|>",
|
| 55 |
+
"lstrip": false,
|
| 56 |
+
"normalized": false,
|
| 57 |
+
"rstrip": false,
|
| 58 |
+
"single_word": false,
|
| 59 |
+
"special": true
|
| 60 |
+
},
|
| 61 |
+
"151650": {
|
| 62 |
+
"content": "<|quad_start|>",
|
| 63 |
+
"lstrip": false,
|
| 64 |
+
"normalized": false,
|
| 65 |
+
"rstrip": false,
|
| 66 |
+
"single_word": false,
|
| 67 |
+
"special": true
|
| 68 |
+
},
|
| 69 |
+
"151651": {
|
| 70 |
+
"content": "<|quad_end|>",
|
| 71 |
+
"lstrip": false,
|
| 72 |
+
"normalized": false,
|
| 73 |
+
"rstrip": false,
|
| 74 |
+
"single_word": false,
|
| 75 |
+
"special": true
|
| 76 |
+
},
|
| 77 |
+
"151652": {
|
| 78 |
+
"content": "<|vision_start|>",
|
| 79 |
+
"lstrip": false,
|
| 80 |
+
"normalized": false,
|
| 81 |
+
"rstrip": false,
|
| 82 |
+
"single_word": false,
|
| 83 |
+
"special": true
|
| 84 |
+
},
|
| 85 |
+
"151653": {
|
| 86 |
+
"content": "<|vision_end|>",
|
| 87 |
+
"lstrip": false,
|
| 88 |
+
"normalized": false,
|
| 89 |
+
"rstrip": false,
|
| 90 |
+
"single_word": false,
|
| 91 |
+
"special": true
|
| 92 |
+
},
|
| 93 |
+
"151654": {
|
| 94 |
+
"content": "<|vision_pad|>",
|
| 95 |
+
"lstrip": false,
|
| 96 |
+
"normalized": false,
|
| 97 |
+
"rstrip": false,
|
| 98 |
+
"single_word": false,
|
| 99 |
+
"special": true
|
| 100 |
+
},
|
| 101 |
+
"151655": {
|
| 102 |
+
"content": "<|image_pad|>",
|
| 103 |
+
"lstrip": false,
|
| 104 |
+
"normalized": false,
|
| 105 |
+
"rstrip": false,
|
| 106 |
+
"single_word": false,
|
| 107 |
+
"special": true
|
| 108 |
+
},
|
| 109 |
+
"151656": {
|
| 110 |
+
"content": "<|video_pad|>",
|
| 111 |
+
"lstrip": false,
|
| 112 |
+
"normalized": false,
|
| 113 |
+
"rstrip": false,
|
| 114 |
+
"single_word": false,
|
| 115 |
+
"special": true
|
| 116 |
+
},
|
| 117 |
+
"151657": {
|
| 118 |
+
"content": "<tool_call>",
|
| 119 |
+
"lstrip": false,
|
| 120 |
+
"normalized": false,
|
| 121 |
+
"rstrip": false,
|
| 122 |
+
"single_word": false,
|
| 123 |
+
"special": false
|
| 124 |
+
},
|
| 125 |
+
"151658": {
|
| 126 |
+
"content": "</tool_call>",
|
| 127 |
+
"lstrip": false,
|
| 128 |
+
"normalized": false,
|
| 129 |
+
"rstrip": false,
|
| 130 |
+
"single_word": false,
|
| 131 |
+
"special": false
|
| 132 |
+
},
|
| 133 |
+
"151659": {
|
| 134 |
+
"content": "<|fim_prefix|>",
|
| 135 |
+
"lstrip": false,
|
| 136 |
+
"normalized": false,
|
| 137 |
+
"rstrip": false,
|
| 138 |
+
"single_word": false,
|
| 139 |
+
"special": false
|
| 140 |
+
},
|
| 141 |
+
"151660": {
|
| 142 |
+
"content": "<|fim_middle|>",
|
| 143 |
+
"lstrip": false,
|
| 144 |
+
"normalized": false,
|
| 145 |
+
"rstrip": false,
|
| 146 |
+
"single_word": false,
|
| 147 |
+
"special": false
|
| 148 |
+
},
|
| 149 |
+
"151661": {
|
| 150 |
+
"content": "<|fim_suffix|>",
|
| 151 |
+
"lstrip": false,
|
| 152 |
+
"normalized": false,
|
| 153 |
+
"rstrip": false,
|
| 154 |
+
"single_word": false,
|
| 155 |
+
"special": false
|
| 156 |
+
},
|
| 157 |
+
"151662": {
|
| 158 |
+
"content": "<|fim_pad|>",
|
| 159 |
+
"lstrip": false,
|
| 160 |
+
"normalized": false,
|
| 161 |
+
"rstrip": false,
|
| 162 |
+
"single_word": false,
|
| 163 |
+
"special": false
|
| 164 |
+
},
|
| 165 |
+
"151663": {
|
| 166 |
+
"content": "<|repo_name|>",
|
| 167 |
+
"lstrip": false,
|
| 168 |
+
"normalized": false,
|
| 169 |
+
"rstrip": false,
|
| 170 |
+
"single_word": false,
|
| 171 |
+
"special": false
|
| 172 |
+
},
|
| 173 |
+
"151664": {
|
| 174 |
+
"content": "<|file_sep|>",
|
| 175 |
+
"lstrip": false,
|
| 176 |
+
"normalized": false,
|
| 177 |
+
"rstrip": false,
|
| 178 |
+
"single_word": false,
|
| 179 |
+
"special": false
|
| 180 |
+
},
|
| 181 |
+
"151665": {
|
| 182 |
+
"content": "<tool_response>",
|
| 183 |
+
"lstrip": false,
|
| 184 |
+
"normalized": false,
|
| 185 |
+
"rstrip": false,
|
| 186 |
+
"single_word": false,
|
| 187 |
+
"special": false
|
| 188 |
+
},
|
| 189 |
+
"151666": {
|
| 190 |
+
"content": "</tool_response>",
|
| 191 |
+
"lstrip": false,
|
| 192 |
+
"normalized": false,
|
| 193 |
+
"rstrip": false,
|
| 194 |
+
"single_word": false,
|
| 195 |
+
"special": false
|
| 196 |
+
},
|
| 197 |
+
"151667": {
|
| 198 |
+
"content": "<think>",
|
| 199 |
+
"lstrip": false,
|
| 200 |
+
"normalized": false,
|
| 201 |
+
"rstrip": false,
|
| 202 |
+
"single_word": false,
|
| 203 |
+
"special": false
|
| 204 |
+
},
|
| 205 |
+
"151668": {
|
| 206 |
+
"content": "</think>",
|
| 207 |
+
"lstrip": false,
|
| 208 |
+
"normalized": false,
|
| 209 |
+
"rstrip": false,
|
| 210 |
+
"single_word": false,
|
| 211 |
+
"special": false
|
| 212 |
+
}
|
| 213 |
+
},
|
| 214 |
+
"additional_special_tokens": [
|
| 215 |
+
"<|im_start|>",
|
| 216 |
+
"<|im_end|>",
|
| 217 |
+
"<|object_ref_start|>",
|
| 218 |
+
"<|object_ref_end|>",
|
| 219 |
+
"<|box_start|>",
|
| 220 |
+
"<|box_end|>",
|
| 221 |
+
"<|quad_start|>",
|
| 222 |
+
"<|quad_end|>",
|
| 223 |
+
"<|vision_start|>",
|
| 224 |
+
"<|vision_end|>",
|
| 225 |
+
"<|vision_pad|>",
|
| 226 |
+
"<|image_pad|>",
|
| 227 |
+
"<|video_pad|>"
|
| 228 |
+
],
|
| 229 |
+
"bos_token": null,
|
| 230 |
+
"chat_template": "{%- if tools %}\n {{- '<|im_start|>system\\n' }}\n {%- if messages[0].role == 'system' %}\n {%- if messages[0].content is string %}\n {{- messages[0].content }}\n {%- else %}\n {%- for content in messages[0].content %}\n {%- if 'text' in content %}\n {{- content.text }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {{- '\\n\\n' }}\n {%- endif %}\n {{- \"# Tools\\n\\nYou may call one or more functions to assist with the user query.\\n\\nYou are provided with function signatures within <tools></tools> XML tags:\\n<tools>\" }}\n {%- for tool in tools %}\n {{- \"\\n\" }}\n {{- tool | tojson }}\n {%- endfor %}\n {{- \"\\n</tools>\\n\\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\\n<tool_call>\\n{\\\"name\\\": <function-name>, \\\"arguments\\\": <args-json-object>}\\n</tool_call><|im_end|>\\n\" }}\n{%- else %}\n {%- if messages[0].role == 'system' %}\n {{- '<|im_start|>system\\n' }}\n {%- if messages[0].content is string %}\n {{- messages[0].content }}\n {%- else %}\n {%- for content in messages[0].content %}\n {%- if 'text' in content %}\n {{- content.text }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {{- '<|im_end|>\\n' }}\n {%- endif %}\n{%- endif %}\n{%- set image_count = namespace(value=0) %}\n{%- set video_count = namespace(value=0) %}\n{%- for message in messages %}\n {%- if message.role == \"user\" %}\n {{- '<|im_start|>' + message.role + '\\n' }}\n {%- if message.content is string %}\n {{- message.content }}\n {%- else %}\n {%- for content in message.content %}\n {%- if content.type == 'image' or 'image' in content or 'image_url' in content %}\n {%- set image_count.value = image_count.value + 1 %}\n {%- if add_vision_id %}Picture {{ image_count.value }}: {% endif -%}\n <|vision_start|><|image_pad|><|vision_end|>\n {%- elif content.type == 'video' or 'video' in content %}\n {%- set video_count.value = video_count.value + 1 %}\n {%- if add_vision_id %}Video {{ video_count.value }}: {% endif -%}\n <|vision_start|><|video_pad|><|vision_end|>\n {%- elif 'text' in content %}\n {{- content.text }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {{- '<|im_end|>\\n' }}\n {%- elif message.role == \"assistant\" %}\n {{- '<|im_start|>' + message.role + '\\n' }}\n {%- if message.content is string %}\n {{- message.content }}\n {%- else %}\n {%- for content_item in message.content %}\n {%- if 'text' in content_item %}\n {{- content_item.text }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {%- if message.tool_calls %}\n {%- for tool_call in message.tool_calls %}\n {%- if (loop.first and message.content) or (not loop.first) %}\n {{- '\\n' }}\n {%- endif %}\n {%- if tool_call.function %}\n {%- set tool_call = tool_call.function %}\n {%- endif %}\n {{- '<tool_call>\\n{\"name\": \"' }}\n {{- tool_call.name }}\n {{- '\", \"arguments\": ' }}\n {%- if tool_call.arguments is string %}\n {{- tool_call.arguments }}\n {%- else %}\n {{- tool_call.arguments | tojson }}\n {%- endif %}\n {{- '}\\n</tool_call>' }}\n {%- endfor %}\n {%- endif %}\n {{- '<|im_end|>\\n' }}\n {%- elif message.role == \"tool\" %}\n {%- if loop.first or (messages[loop.index0 - 1].role != \"tool\") %}\n {{- '<|im_start|>user' }}\n {%- endif %}\n {{- '\\n<tool_response>\\n' }}\n {%- if message.content is string %}\n {{- message.content }}\n {%- else %}\n {%- for content in message.content %}\n {%- if content.type == 'image' or 'image' in content or 'image_url' in content %}\n {%- set image_count.value = image_count.value + 1 %}\n {%- if add_vision_id %}Picture {{ image_count.value }}: {% endif -%}\n <|vision_start|><|image_pad|><|vision_end|>\n {%- elif content.type == 'video' or 'video' in content %}\n {%- set video_count.value = video_count.value + 1 %}\n {%- if add_vision_id %}Video {{ video_count.value }}: {% endif -%}\n <|vision_start|><|video_pad|><|vision_end|>\n {%- elif 'text' in content %}\n {{- content.text }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {{- '\\n</tool_response>' }}\n {%- if loop.last or (messages[loop.index0 + 1].role != \"tool\") %}\n {{- '<|im_end|>\\n' }}\n {%- endif %}\n {%- endif %}\n{%- endfor %}\n{%- if add_generation_prompt %}\n {{- '<|im_start|>assistant\\n' }}\n{%- endif %}\n",
|
| 231 |
+
"clean_up_tokenization_spaces": false,
|
| 232 |
+
"eos_token": "<|im_end|>",
|
| 233 |
+
"errors": "replace",
|
| 234 |
+
"model_max_length": 262144,
|
| 235 |
+
"pad_token": "<|endoftext|>",
|
| 236 |
+
"split_special_tokens": false,
|
| 237 |
+
"tokenizer_class": "Qwen2Tokenizer",
|
| 238 |
+
"unk_token": null
|
| 239 |
+
}
|
transformer/config.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_class_name": "Cosmos3OmniTransformer",
|
| 3 |
+
"_diffusers_version": "0.39.0.dev0",
|
| 4 |
+
"action_dim": 32,
|
| 5 |
+
"action_gen": false,
|
| 6 |
+
"attention_bias": false,
|
| 7 |
+
"attention_dropout": 0.0,
|
| 8 |
+
"base_fps": 16,
|
| 9 |
+
"enable_fps_modulation": true,
|
| 10 |
+
"head_dim": 128,
|
| 11 |
+
"hidden_size": 5120,
|
| 12 |
+
"intermediate_size": 25600,
|
| 13 |
+
"latent_channel": 48,
|
| 14 |
+
"latent_patch_size": 2,
|
| 15 |
+
"num_attention_heads": 64,
|
| 16 |
+
"num_embodiment_domains": 32,
|
| 17 |
+
"num_hidden_layers": 64,
|
| 18 |
+
"num_key_value_heads": 8,
|
| 19 |
+
"patch_latent_dim": 192,
|
| 20 |
+
"rms_norm_eps": 1e-06,
|
| 21 |
+
"rope_axes_dim": [
|
| 22 |
+
24,
|
| 23 |
+
20,
|
| 24 |
+
20
|
| 25 |
+
],
|
| 26 |
+
"rope_scaling": {
|
| 27 |
+
"mrope_interleaved": true,
|
| 28 |
+
"mrope_section": [
|
| 29 |
+
24,
|
| 30 |
+
20,
|
| 31 |
+
20
|
| 32 |
+
],
|
| 33 |
+
"rope_type": "default"
|
| 34 |
+
},
|
| 35 |
+
"rope_theta": 5000000,
|
| 36 |
+
"sound_dim": null,
|
| 37 |
+
"sound_gen": false,
|
| 38 |
+
"sound_latent_fps": 25,
|
| 39 |
+
"timestep_scale": 0.001,
|
| 40 |
+
"unified_3d_mrope_reset_spatial_ids": true,
|
| 41 |
+
"unified_3d_mrope_temporal_modality_margin": 15000,
|
| 42 |
+
"vocab_size": 151936
|
| 43 |
+
}
|
transformer/diffusion_pytorch_model-00001-of-00004.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7e2aa2e718722509028b354db2f24616f8e10a9f7c2782db7e2f3eecc9bce490
|
| 3 |
+
size 9964515442
|
transformer/diffusion_pytorch_model-00002-of-00004.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:98d10b08cd826c462d0c6de64a3640648ea03841af48abdac24b10405ed7caf5
|
| 3 |
+
size 9948271838
|
transformer/diffusion_pytorch_model-00003-of-00004.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9a417ced6bebae39de4df3eaa58f744630d46e7715e9773d34ec00787dae2eca
|
| 3 |
+
size 9948271838
|
transformer/diffusion_pytorch_model-00004-of-00004.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a9416e9e32370e3e34ff2281ea90d965a3d54cc3e5956eb2abd0e0210cab8eb2
|
| 3 |
+
size 8419116030
|
transformer/diffusion_pytorch_model.safetensors.index.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
transformer/modelopt_state.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d622a0d180c70ff7396db6e5abafd855072d8080fc9e66bdea2eb6489d0e1560
|
| 3 |
+
size 1295319
|
vae/config.json
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_class_name": "AutoencoderKLWan",
|
| 3 |
+
"_diffusers_version": "0.39.0",
|
| 4 |
+
"_name_or_path": "Wan-AI/Wan2.2-TI2V-5B-Diffusers",
|
| 5 |
+
"attn_scales": [],
|
| 6 |
+
"base_dim": 160,
|
| 7 |
+
"clip_output": false,
|
| 8 |
+
"decoder_base_dim": 256,
|
| 9 |
+
"dim_mult": [
|
| 10 |
+
1,
|
| 11 |
+
2,
|
| 12 |
+
4,
|
| 13 |
+
4
|
| 14 |
+
],
|
| 15 |
+
"dropout": 0.0,
|
| 16 |
+
"in_channels": 12,
|
| 17 |
+
"is_residual": true,
|
| 18 |
+
"latents_mean": [
|
| 19 |
+
-0.2289,
|
| 20 |
+
-0.0052,
|
| 21 |
+
-0.1323,
|
| 22 |
+
-0.2339,
|
| 23 |
+
-0.2799,
|
| 24 |
+
0.0174,
|
| 25 |
+
0.1838,
|
| 26 |
+
0.1557,
|
| 27 |
+
-0.1382,
|
| 28 |
+
0.0542,
|
| 29 |
+
0.2813,
|
| 30 |
+
0.0891,
|
| 31 |
+
0.157,
|
| 32 |
+
-0.0098,
|
| 33 |
+
0.0375,
|
| 34 |
+
-0.1825,
|
| 35 |
+
-0.2246,
|
| 36 |
+
-0.1207,
|
| 37 |
+
-0.0698,
|
| 38 |
+
0.5109,
|
| 39 |
+
0.2665,
|
| 40 |
+
-0.2108,
|
| 41 |
+
-0.2158,
|
| 42 |
+
0.2502,
|
| 43 |
+
-0.2055,
|
| 44 |
+
-0.0322,
|
| 45 |
+
0.1109,
|
| 46 |
+
0.1567,
|
| 47 |
+
-0.0729,
|
| 48 |
+
0.0899,
|
| 49 |
+
-0.2799,
|
| 50 |
+
-0.123,
|
| 51 |
+
-0.0313,
|
| 52 |
+
-0.1649,
|
| 53 |
+
0.0117,
|
| 54 |
+
0.0723,
|
| 55 |
+
-0.2839,
|
| 56 |
+
-0.2083,
|
| 57 |
+
-0.052,
|
| 58 |
+
0.3748,
|
| 59 |
+
0.0152,
|
| 60 |
+
0.1957,
|
| 61 |
+
0.1433,
|
| 62 |
+
-0.2944,
|
| 63 |
+
0.3573,
|
| 64 |
+
-0.0548,
|
| 65 |
+
-0.1681,
|
| 66 |
+
-0.0667
|
| 67 |
+
],
|
| 68 |
+
"latents_std": [
|
| 69 |
+
0.4765,
|
| 70 |
+
1.0364,
|
| 71 |
+
0.4514,
|
| 72 |
+
1.1677,
|
| 73 |
+
0.5313,
|
| 74 |
+
0.499,
|
| 75 |
+
0.4818,
|
| 76 |
+
0.5013,
|
| 77 |
+
0.8158,
|
| 78 |
+
1.0344,
|
| 79 |
+
0.5894,
|
| 80 |
+
1.0901,
|
| 81 |
+
0.6885,
|
| 82 |
+
0.6165,
|
| 83 |
+
0.8454,
|
| 84 |
+
0.4978,
|
| 85 |
+
0.5759,
|
| 86 |
+
0.3523,
|
| 87 |
+
0.7135,
|
| 88 |
+
0.6804,
|
| 89 |
+
0.5833,
|
| 90 |
+
1.4146,
|
| 91 |
+
0.8986,
|
| 92 |
+
0.5659,
|
| 93 |
+
0.7069,
|
| 94 |
+
0.5338,
|
| 95 |
+
0.4889,
|
| 96 |
+
0.4917,
|
| 97 |
+
0.4069,
|
| 98 |
+
0.4999,
|
| 99 |
+
0.6866,
|
| 100 |
+
0.4093,
|
| 101 |
+
0.5709,
|
| 102 |
+
0.6065,
|
| 103 |
+
0.6415,
|
| 104 |
+
0.4944,
|
| 105 |
+
0.5726,
|
| 106 |
+
1.2042,
|
| 107 |
+
0.5458,
|
| 108 |
+
1.6887,
|
| 109 |
+
0.3971,
|
| 110 |
+
1.06,
|
| 111 |
+
0.3943,
|
| 112 |
+
0.5537,
|
| 113 |
+
0.5444,
|
| 114 |
+
0.4089,
|
| 115 |
+
0.7468,
|
| 116 |
+
0.7744
|
| 117 |
+
],
|
| 118 |
+
"num_res_blocks": 2,
|
| 119 |
+
"out_channels": 12,
|
| 120 |
+
"patch_size": 2,
|
| 121 |
+
"scale_factor_spatial": 16,
|
| 122 |
+
"scale_factor_temporal": 4,
|
| 123 |
+
"temperal_downsample": [
|
| 124 |
+
false,
|
| 125 |
+
true,
|
| 126 |
+
true
|
| 127 |
+
],
|
| 128 |
+
"z_dim": 48
|
| 129 |
+
}
|
vae/diffusion_pytorch_model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:230496cb59ff85bc9c040487737c4062480cb61c71e697b197b4c30142f2a0da
|
| 3 |
+
size 1409400600
|
validate_cosmos3_i2v4step_fp8.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""
|
| 3 |
+
Standalone re-validation of the Cosmos3-Super-Image2Video-4Step FP8 quantization
|
| 4 |
+
(quantize_cosmos3_i2v4step_streaming.py). Exists because the first --smoke run's
|
| 5 |
+
render was invalid: it used the pipeline's default 35-step/guidance=6.0 schedule
|
| 6 |
+
instead of this checkpoint's trained 4-step sde schedule (a diffusers version gap --
|
| 7 |
+
Cosmos3OmniPipeline doesn't pass the scheduler_config.json's fixed_step_sampler_config
|
| 8 |
+
through to scheduler.set_timesteps; see _force_fixed_step_schedule in
|
| 9 |
+
serve_cosmos3_i2v4step_diffusers.py for the full rationale).
|
| 10 |
+
|
| 11 |
+
NOTE: export_hf_checkpoint() (what the quantize script wrote to ./cosmos3-i2v4step-fp8)
|
| 12 |
+
is NVIDIA's *deployment* format for vLLM/TRT-LLM -- it has no modelopt_state.pth, so
|
| 13 |
+
diffusers' from_pretrained / load_cosmos3_modelopt.py can't load it directly (same gap
|
| 14 |
+
repackage_for_hf.py exists to solve for the base model). Rather than write a second
|
| 15 |
+
~65GB copy to disk just to validate, this rebuilds the quantized transformer in memory
|
| 16 |
+
via the same build_quantized_transformer() used during quantization (re-streams the
|
| 17 |
+
121GB source once) and renders straight from that -- no extra disk footprint beyond the
|
| 18 |
+
output clip. If you want a real servable drop-in repo afterward, run
|
| 19 |
+
repackage_for_hf_i2v4step.py (that DOES need the disk headroom).
|
| 20 |
+
|
| 21 |
+
USAGE
|
| 22 |
+
python validate_cosmos3_i2v4step_fp8.py --format fp8 --image out.png
|
| 23 |
+
"""
|
| 24 |
+
import argparse
|
| 25 |
+
import os
|
| 26 |
+
|
| 27 |
+
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
|
| 28 |
+
|
| 29 |
+
import torch
|
| 30 |
+
from PIL import Image
|
| 31 |
+
|
| 32 |
+
from serve_cosmos3_i2v4step_diffusers import build_quantized_transformer, make_pipeline
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def main():
|
| 36 |
+
ap = argparse.ArgumentParser()
|
| 37 |
+
ap.add_argument("--format", choices=["fp8", "nvfp4"], default="fp8")
|
| 38 |
+
ap.add_argument("--gpu-mem-fraction", type=float, default=0.85)
|
| 39 |
+
ap.add_argument("--image", default="out.png")
|
| 40 |
+
ap.add_argument("--num-frames", type=int, default=49)
|
| 41 |
+
ap.add_argument("--height", type=int, default=512)
|
| 42 |
+
ap.add_argument("--width", type=int, default=512)
|
| 43 |
+
ap.add_argument("--seed", type=int, default=1234)
|
| 44 |
+
ap.add_argument("--out", default="cosmos3_i2v4step_fp8_validate.mp4")
|
| 45 |
+
ap.add_argument(
|
| 46 |
+
"--prompt",
|
| 47 |
+
default="The camera holds static as the scene continues naturally, with subtle motion and realistic physics.",
|
| 48 |
+
)
|
| 49 |
+
args = ap.parse_args()
|
| 50 |
+
|
| 51 |
+
print(f"[build] rebuilding quantized ({args.format}) transformer in memory ...")
|
| 52 |
+
model = build_quantized_transformer(args.format, args.gpu_mem_fraction)
|
| 53 |
+
pipe = make_pipeline(model) # includes _force_fixed_step_schedule on pipe.scheduler
|
| 54 |
+
|
| 55 |
+
cond_image = Image.open(args.image).convert("RGB")
|
| 56 |
+
|
| 57 |
+
print(f"[render] {args.num_frames} frames @ {args.height}x{args.width}, seed={args.seed}")
|
| 58 |
+
with torch.inference_mode():
|
| 59 |
+
result = pipe(
|
| 60 |
+
prompt=args.prompt,
|
| 61 |
+
negative_prompt="",
|
| 62 |
+
image=cond_image,
|
| 63 |
+
num_frames=args.num_frames,
|
| 64 |
+
height=args.height,
|
| 65 |
+
width=args.width,
|
| 66 |
+
num_inference_steps=4, # no-op once patched; kept for clarity
|
| 67 |
+
guidance_scale=1.0, # CFG is distilled out of this checkpoint
|
| 68 |
+
generator=torch.Generator(device="cuda").manual_seed(args.seed),
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
from diffusers.utils import export_to_video
|
| 72 |
+
export_to_video(result.video, args.out, fps=24)
|
| 73 |
+
print(f"[done] wrote {args.out}")
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
if __name__ == "__main__":
|
| 77 |
+
main()
|
video_preprocessor_config.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"size": {
|
| 3 |
+
"longest_edge": 25165824,
|
| 4 |
+
"shortest_edge": 4096
|
| 5 |
+
},
|
| 6 |
+
"patch_size": 16,
|
| 7 |
+
"temporal_patch_size": 2,
|
| 8 |
+
"merge_size": 2,
|
| 9 |
+
"image_mean": [
|
| 10 |
+
0.5,
|
| 11 |
+
0.5,
|
| 12 |
+
0.5
|
| 13 |
+
],
|
| 14 |
+
"image_std": [
|
| 15 |
+
0.5,
|
| 16 |
+
0.5,
|
| 17 |
+
0.5
|
| 18 |
+
],
|
| 19 |
+
"processor_class": "Qwen3VLProcessor",
|
| 20 |
+
"video_processor_type": "Qwen3VLVideoProcessor"
|
| 21 |
+
}
|
vocab.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|