[Feature]【Hackathon 10th Spring No.48】SD3 and Flux diffusion model implementation#7505
Conversation
|
Thanks for your contribution! |
ad256dd to
72a7d10
Compare
PaddlePaddle-bot
left a comment
There was a problem hiding this comment.
🤖 AI Code Review |
2026-04-20 14:16 CST
📋 Review 摘要
PR 概述:为 FastDeploy 新增自包含的 SD3 / Flux 扩散模型推理模块,包含 DiT 组网、VAE、调度器、文本编码器及统一推理引擎。
变更范围:fastdeploy/model_executor/diffusion_models/(新增模块)、tests/diffusion_models/、scripts/diffusion_models/
影响面 Tag:Models
📝 PR 规范检查
PR 标题和描述均符合规范,[Feature] Tag 合法,Motivation/Modifications/Usage/Tests 描述完整。
问题
| 级别 | 文件 | 概述 |
|---|---|---|
| 🔴 Bug | parallel.py:56 |
TP 扫描模式名称 mlp.0/mlp.2 与实际模型属性名 ff.0/ff.2 不匹配,将导致 TP>1 时零层被识别 |
| 🟡 建议 | engine.py:223 |
paddle.seed() 是全局操作,会影响调用方的随机状态 |
| 🟡 建议 | engine.py:325 |
SD3 CFG 每步做两次独立 transformer forward,可用 batch 合并优化 |
总体评价
实现质量较高,模块设计自包含、架构清晰、文档完善、测试覆盖充分(79 tests)。SD3/Flux 的关键对齐细节(center-crop pos embed、QK norms、sigma schedule)均有考虑。主要问题是 parallel.py 中 TP 模式名与实际模型属性名不一致,虽然当前单 GPU 为 no-op 不影响功能,但在后续 TP 集成时会导致 bug。建议在本 PR 中修复以避免后续贡献者踩坑。
| _COLUMN_PARALLEL_PATTERNS = ( | ||
| "attn_qkv", # Flux/SD3: joint QKV projection | ||
| "attn_qkv_context", # Flux/SD3: context stream QKV | ||
| "mlp.0", # MLP gate (first linear in Sequential) |
There was a problem hiding this comment.
🔴 Bug TP 模式名称与实际模型属性名不匹配
_COLUMN_PARALLEL_PATTERNS 和 _ROW_PARALLEL_PATTERNS 中的 "mlp.0" / "mlp.2" / "mlp_context.0" / "mlp_context.2" 与 Flux/SD3 DiT 模型中实际的属性名不一致:
FluxDoubleStreamBlock/SD3JointTransformerBlock使用self.ff(非self.mlp)和self.ff_context(非self.mlp_context)FluxSingleStreamBlock使用self.proj_mlp(非self.mlp)
因此 named_modules() 返回的层名类似 transformer_blocks.0.ff.0 而非 transformer_blocks.0.mlp.0,导致 TP 扫描时 MLP 层全部漏匹配。虽然当前单 GPU 下为 no-op,但后续 TP 集成时会导致 MLP 层无法被正确替换。
建议修复:
_COLUMN_PARALLEL_PATTERNS = (
"attn_qkv",
"attn_qkv_context",
"ff.0", # DoubleStream/JointTransformer MLP gate
"ff_context.0", # Context MLP gate
"proj_mlp", # SingleStream MLP projection
)
_ROW_PARALLEL_PATTERNS = (
"attn_out",
"attn_out_context",
"ff.2", # DoubleStream/JointTransformer MLP down
"ff_context.2", # Context MLP down
"proj_out",
)|
|
||
| # 3. 噪声初始化 (Initialize noise) | ||
| if seed is not None: | ||
| paddle.seed(seed) |
There was a problem hiding this comment.
🟡 建议 paddle.seed() 是全局操作,会污染调用方的随机状态
paddle.seed(seed) 设置的是全局随机种子,会影响后续所有 paddle.randn() 调用——包括调用方自己的代码。如果用户在循环中多次调用 engine.generate(),第二次以后的随机状态可能被意外改变。
建议使用局部 Generator 隔离随机状态(如果 PaddlePaddle 版本支持),或者在设置种子后立即生成 latent 噪声,并在之后恢复原始随机状态。同样的问题也存在于 _generate_sd3 的第 305 行。
| ) | ||
|
|
||
| # 分类器自由引导 (Classifier-free guidance) | ||
| if do_cfg: |
There was a problem hiding this comment.
🟡 建议 SD3 CFG 实现每步两次 transformer forward 可优化
当前 CFG 实现在去噪循环的每一步都独立调用两次 self.transformer()(条件 + 无条件)。更高效的做法是将条件和无条件输入沿 batch 维度合并为一次 forward,然后在输出端拆分:
# 合并 batch: [2B, ...]
latents_input = paddle.concat([latents, latents], axis=0)
embeds_input = paddle.concat([prompt_embeds, uncond_embeds], axis=0)
pooled_input = paddle.concat([pooled_embeds, uncond_pooled], axis=0)
noise_pred_all = self.transformer(...)
noise_pred, noise_pred_uncond = noise_pred_all.chunk(2, axis=0)
noise_pred = noise_pred_uncond + guidance * (noise_pred - noise_pred_uncond)这样可以利用 batch 并行性,减少约 40% 的去噪延迟(尤其是在 GPU 利用率不满时效果显著)。可作为后续优化 TODO。
Motivation
实现 RFC 设计文档 (community#1316) 中的核心交付:为 FastDeploy 新增自包含 SD3 / Flux 扩散模型推理模块(Hackathon 10th Spring No.48)。
本 PR 提供可独立运行的 Stable Diffusion 3 与 FLUX.1 推理流水线:
模块为自包含设计,放置于
fastdeploy/model_executor/diffusion_models/,不修改现有 FD 推理流程。与 FD 框架的深度集成(FDConfig 注册、ModelCategory 路由、fdctl serve 入口)作为后续社区贡献接口预留。Modifications
交付物一:SD3 + Flux 扩散模型组网
diffusion_models/models/flux_dit.pydiffusion_models/models/sd3_dit.pydiffusion_models/components/vae.pydiffusion_models/components/text_encoder.pydiffusion_models/components/weight_utils.pydiffusion_models/schedulers/flow_matching.pyscheduling_flow_match_euler_discrete), Euler step, shift parameterdiffusion_models/engine.pydiffusion_models/config.pydiffusion_models/README.md交付物二:自定义算子
经分析,SD3/Flux 推理流程可完全使用 PaddlePaddle 标准算子实现,无需额外自定义 CUDA 算子。
交付物三:并行/量化层扫描(准备工作,非完整适配)
diffusion_models/parallel.py关键实现细节(HF diffusers 对齐验证)
PatchEmbed.cropped_pos_embed,含越界 ValueError 保护elementwise_affine=False(weight_attr=False, bias_attr=False)对齐 HFAdaLayerNormContinuouslinspace(1, 1/N_train, N) + [0]对齐 HFscheduling_flow_match_euler_discrete.pyUsage or Command
Accuracy Tests
全部测试在 AI Studio A800-SXM4-80GB (SM80, CUDA 13.0, PaddlePaddle 3.3.0) 上验证通过。
测试文件
test_dit_numerical_invariants.pytest_fd_integration.pytest_pipeline_contracts.pytest_numerical_references.pytest_flux_gpu.pyconftest.py测试结果
全部 79/79 测试通过,0 失败。
Checklist
fastdeploy/model_executor/diffusion_models/)README.md)parallel.py— 候选层名称映射,单 GPU no-op)