Uh oh!
There was an error while loading. Please reload this page.
Add Echo modular pipeline - #14696
Conversation
HuggingFaceDocBuilderDev
commented
Sep 4, 2026
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 feedbacks
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
@yiyixuxu Thanks for the review — all feedback is addressed in 64f423a and 679db3f.
Validation:
Self-review found no remaining blocking issue in this update. The repository-wide Could you please take another look? |
yiyixuxu
left a comment
There was a problem hiding this comment.
thanks!
i left some more comments
| mel = torch.log(torch.clamp(mel_transform(waveform), min=1e-5)).permute(0, 2, 1).unsqueeze(0) | ||
| latents = audio_vae.encode(mel.to(audio_vae.dtype)).latent_dist.mode() | ||
| latents = _pack_audio_latents(latents) |
There was a problem hiding this comment.
is it possible to make the audio latent and video latent consistent? i.e. both normalized in encoder and packed in before_denoise? see a bit more write up here #14730
| latent_height = block_state.height // components.vae_spatial_compression_ratio | ||
| latent_width = block_state.width // components.vae_spatial_compression_ratio |
There was a problem hiding this comment.
| latent_height=block_state.height//components.vae_spatial_compression_ratio | |
| latent_width=block_state.width//components.vae_spatial_compression_ratio | |
| _, _, latent_height, latent_width=memory_video_latents[0].shape |
| InputParam.template("height", default=512), | ||
| InputParam.template("width", default=704), |
There was a problem hiding this comment.
| InputParam.template("height", default=512), | |
| InputParam.template("width", default=704), |
I think we can derive from latent shape
| def __call__(self, components, block_state: BlockState, i: int, sigma: float): | ||
| batch_size = block_state.latents.shape[0] | ||
| transformer_dtype = components.transformer.dtype | ||
| video_context = self._expand_batch(block_state.connector_prompt_embeds, batch_size).to(transformer_dtype) |
There was a problem hiding this comment.
can we have a dedicated step to expand all the inputs? like https://github.com/huggingface/diffusers/blob/main/src/diffusers/modular_pipelines/krea2/before_denoise.py#L46
| # auto_docstring | ||
| class EchoDenoiseLoopStep(LoopSequentialPipelineBlocks): |
There was a problem hiding this comment.
ohh this is typically inside denoise.py (even though it is a multi-block) - sorry if I've confused you earlier
| latent_num_frames = (block_state.num_frames - 1) // components.vae_temporal_compression_ratio + 1 | ||
| latent_height = block_state.height // components.vae_spatial_compression_ratio | ||
| latent_width = block_state.width // components.vae_spatial_compression_ratio | ||
| latents = _unpack_latents( |
There was a problem hiding this comment.
I think we can move the unpack to core denoise blocks (see #14730)
What does this PR do?
Adds official Diffusers Modular Pipeline support for Echo, a long-video model that generates synchronized video and audio with cross-shot memory.
This supersedes #13910 with a modular implementation that incorporates the earlier review feedback:
diffusers.modular_pipelines.echopackage and the publicEchoModularPipeline/EchoBlocksAPIsscripts/instead of adding an original-checkpoint runtime pipelineOfficial resources:
Closes#13909
Supersedes #13910
Testing
make stylemake fix-copiesmake qualityPYTHONPATH=src python -m pytest -q tests/modular_pipelines/echo/test_modular_pipeline_echo.pyAI-assisted self-review
Codex was used to help review, refactor, test, and prepare this contribution. The final diff was reviewed using the repository's model-integration and self-review guidance.
The final self-review found no blocking correctness issues. Echo has its own public package and naming throughout; existing lower-level Diffusers component types are reused only as implementation dependencies. Memory-slot count, short-audio handling, variable audio lengths, response-aware 9.62-second cropping, deterministic DMD re-noising, mixed-precision decoding, loading, save/load, workflow, and memory behavior are covered by the test suite.
Validation scope: the final pass used the public
Echo-Team/tiny-echo-modular-pipefixture on CPU. A full production-checkpoint conversion and end-to-end GPU inference run was not repeated in this final pass.Before submitting
self-reviewskill on the diff?Who can review?
@asomoza@yiyixuxu