Cosmos3 Distilled support#14177
Conversation
yiyixuxu
left a comment
There was a problem hiding this comment.
thanks!
i left some comments
|
Hi @yzhautouskay, thanks for the PR! It does not appear to link an issue it fixes. If this PR addresses an existing issue, please add a closing keyword (e.g. |
|
thanks @yiyixuxu! I've refactored it to have separate |
|
@yzhautouskay can you resolve the conflict? |
177ee1e to
3ac7ec0
Compare
3ac7ec0 to
abb37e7
Compare
yiyixuxu
left a comment
There was a problem hiding this comment.
thanks, I left some comments
| ] | ||
|
|
||
|
|
||
| def _fake_distilled_components(t_list=(1.0, 0.75, 0.5, 0.25)): |
There was a problem hiding this comment.
can you update the test to use ModularPipelineTesterMixin?
https://github.com/huggingface/diffusers/blob/main/tests/modular_pipelines/flux2/test_modular_pipeline_flux2_klein.py
There was a problem hiding this comment.
Done, distilled tests now use ModularPipelineTesterMixin. For now tiny fixture lives under my personal account at yzhautouskay/tiny-cosmos3-distilled-modular-pipe
Could you create hf-internal-testing/tiny-cosmos3-distilled-modular-pipe and copy it over ? I'll then flip the TINY_DISTILLED_REPO constant in the test (and pretrained_model_name_or_path will need to be changed for components in modular_model_index.json)
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
yiyixuxu
left a comment
There was a problem hiding this comment.
thanks, I left some final comments on tests & docs, we can merge after these are addressed
| return SimpleNamespace(_execution_device="cpu", config=config) | ||
|
|
||
|
|
||
| def test_cosmos3_distilled_vae_encoder_select_block(): |
There was a problem hiding this comment.
can you move this test to TestCosmos3DistilledModularPipelineFast,
you can do something like
def test_vae_encoder_rejects_image_and_video_together(self):
vae_encoder = Cosmos3DistilledBlocks().sub_blocks["vae_encoder"]
vae_pipe = vae_encoder.init_pipeline(self.pretrained_model_name_or_path)
vae_pipe.load_components(torch_dtype=torch.float32)
with pytest.raises(ValueError, match="either image or video"):
vae_pipe(image=image, video=video, num_frames=5, height=32, width=32)| vae_encoder.select_block(image=object(), video=object()) | ||
|
|
||
|
|
||
| def test_cosmos3_distilled_set_timesteps_declares_distilled_configs(): |
There was a problem hiding this comment.
can you move this test to the TestCosmos3DistilledModularPipelineFast too
Also, it'd be more meaningful to test the final pipeline's config
pipe = self.pipeline_class()
assert pipe.config.is_distilled is True
assert pipe.config.distilled_sigmas is None | def test_cosmos3_distilled_text_encoder_requires_str_prompt(): | ||
| Cosmos3DistilledTextEncoderStep._check_inputs(SimpleNamespace(prompt="a robot")) | ||
| with pytest.raises(ValueError, match="`prompt` must be a str"): | ||
| Cosmos3DistilledTextEncoderStep._check_inputs(SimpleNamespace(prompt=["a robot", "another"])) |
There was a problem hiding this comment.
can you move this test to the TestCosmos3DistilledModularPipelineFast too
also think it is more meaningful to test this behavior on final pipeline, instead of the _check_inputs
def test_rejects_batched_prompts(self):
pipe = self.get_pipeline()
inputs = self.get_dummy_inputs()
inputs["prompt"] = ["a robot", "another"]
with pytest.raises(ValueError, match="..."):
pipe(**inputs, output=self.output_name)| def test_cosmos3_distilled_text_encoder_omits_negative_prompt(): | ||
| input_names = {inp.name for inp in Cosmos3DistilledTextEncoderStep().inputs} | ||
| assert "prompt" in input_names | ||
| assert "negative_prompt" not in input_names |
There was a problem hiding this comment.
can you remove this test for now? we can extend our base test here to support a "not_params"
https://github.com/huggingface/diffusers/blob/main/tests/modular_pipelines/test_modular_pipelines_common.py#L165
| def _fake_distilled_components(sigmas=(1.0, 0.9375, 0.8333333333333334, 0.625)): | ||
| config = SimpleNamespace(distilled_sigmas=list(sigmas)) | ||
| return SimpleNamespace(_execution_device="cpu", config=config) |
There was a problem hiding this comment.
| def _fake_distilled_components(sigmas=(1.0, 0.9375, 0.8333333333333334, 0.625)): | |
| config = SimpleNamespace(distilled_sigmas=list(sigmas)) | |
| return SimpleNamespace(_execution_device="cpu", config=config) |
| Cosmos3DistilledTextEncoderStep._check_inputs(SimpleNamespace(prompt=["a robot", "another"])) | ||
|
|
||
|
|
||
| def test_cosmos3_distilled_set_timesteps_rejects_step_count_override(): |
There was a problem hiding this comment.
same comment https://github.com/huggingface/diffusers/pull/14177/changes#r3598260664
I think it's more meaningful to test all the behavior on final pipeline (not individual steps)
def test_rejects_num_inference_steps_override(self):
pipe = self.get_pipeline()
inputs = self.get_dummy_inputs()
inputs["num_inference_steps"] = 10
with pytest.raises(..."):
pipe(**inputs, output=self.output_name)| step(_fake_distilled_components(), state) | ||
|
|
||
|
|
||
| def test_cosmos3_distilled_set_timesteps_rejects_guidance_override(): |
There was a problem hiding this comment.
def test_rejects_guidance_scale_override(self):
pipe = self.get_pipeline()
inputs = self.get_dummy_inputs()
inputs["guidance_scale"] = 3.0
with pytest.raises(ValueError, match="`guidance_scale` must be 1.0"):
pipe(**inputs, output=self.output_name)| step(_fake_distilled_components(), state) | ||
|
|
||
|
|
||
| def test_cosmos3_distilled_set_timesteps_requires_distilled_sigmas(): |
| Load a distilled repo and call the pipeline **without** `num_inference_steps` or | ||
| `guidance_scale`; `Cosmos3DistilledSetTimestepsStep` reads the fixed step count from the | ||
| scheduler config and forces `guidance_scale=1.0`. Because classifier-free guidance is baked | ||
| into the weights, `negative_prompt` is not supported (passing one raises an error). |
There was a problem hiding this comment.
| into the weights, `negative_prompt` is not supported (passing one raises an error). | |
| into the weights, `negative_prompt` is not supported (passing one raises a warning and get ignored). |
| ### Distilled (few-step) text-to-image and image-to-video | ||
|
|
||
| Few-step distilled checkpoints ship a fixed sigma schedule in | ||
| `scheduler.config.fixed_step_sampler_config.t_list` and bake classifier-free guidance into |
There was a problem hiding this comment.
I think we need to udpate the doc here, no? now it is a pipeline config
|
|
||
| # TODO: move this fixture to `hf-internal-testing/tiny-cosmos3-distilled-modular-pipe` and update the | ||
| # repo name here. Hosted on a personal account for now so the PR can be tested. | ||
| TINY_DISTILLED_REPO = "yzhautouskay/tiny-cosmos3-distilled-modular-pipe" |
There was a problem hiding this comment.
i created the repo here if you want to PR there https://huggingface.co/hf-internal-testing/tiny-cosmos3-distilled-modular-pipe
What does this PR do?
Cosmos3 distilled (few-step) support
Adds inference support for the distilled few-step Cosmos3 checkpoints through the
modular pipeline (
Cosmos3OmniModularPipeline).Checkpoints supported
nvidia/Cosmos3-Super-Text2Image-4Step(distilled T2I)nvidia/Cosmos3-Super-Image2Video-4Step(distilled I2V)Both ship a
FlowMatchEulerDiscreteSchedulerwith a fixed sigma schedule(
scheduler.config.fixed_step_sampler_config.t_list) and bake classifier-freeguidance into the weights. They are only supported via the modular pipeline; the
task-based
Cosmos3OmniPipelinedoes not implement the distilled contract.Before submitting
.ai/review-rules.md?documentation guidelines, and
here are tips on formatting docstrings.
Who can review?
Anyone in the community is free to review the PR once the tests have passed. Feel free to tag
members/contributors who may be interested in your PR.