Prhub

#22289 [Bugfix] multimodal_gen(hunyuan3d): honor config precisions for delight/paint

原始 PR 作者 jy-song-hub 合并时间 2026-05-20 10:38 文件变更 1 提交数 6 评论 5 代码增减 +34 / -4

执行摘要

修复 Hunyuan3D 精度配置和负提示词

PR body 指出,Hunyuan3D Paint 之前硬编码 fp16,忽略了管道配置中的 dit_precisionvae_precision,在 CPU/MPS 上因缺乏半精度支持而崩溃,且不同管道间的精度行为不一致。此外,delight 阶段忽略了 delight_negative_prompt

值得精读,尤其是理解如何在现有代码中通过 PRECISION_TO_TYPE 和简单回退逻辑实现精度配置的兼容性修复。对于类似的多模态生成模块有参考价值。

讨论亮点

PR 没有 review 评论,只有批准。作者在 issue 评论中提供了本地验证用的单元测试代码(未包含在 PR 内),并解释了精度回退的安全性。

实现拆解

  1. 导入 PRECISION_TO_TYPE 映射:在 python/sglang/multimodal_gen/runtime/pipelines_core/stages/hunyuan3d_paint.py 中添加导入,用于将配置字符串(如 "fp16")转换为 torch.dtype
  2. 修复 Delight 管道加载:在 _load_delight_model 中,从配置中读取 dit_precision(默认 "fp16"),通过 PRECISION_TO_TYPE 获取对应 dtype,若设备为 CPU/MPS 且 dtype 为半精度则回退到 fp32;随后使用该 dtype 加载和移动管道。
  3. 修复 VAE 和 UNet 加载:在 _do_load_paint 中,分别处理 VAE 的 vae_precision(默认 "fp32")和 UNet 的 dit_precision(默认 "fp16"),同样添加 CPU/MPS 回退逻辑。
  4. 传递 delight_negative_prompt:在 _run_delight 的管道调用中,新增 negative_prompt 参数,其值从 self.config.delight_negative_prompt 获取(默认空字符串)。
文件 模块 状态 重要度
python/sglang/multimodal_gen/runtime/pipelines_core/stages/hunyuan3d_paint.py 生成管道 modified 7.01

关键符号

_load_delight_model _do_load_paint _run_delight

关键源码片段

python/sglang/multimodal_gen/runtime/pipelines_core/stages/hunyuan3d_paint.py dependency-wiring

唯一变更文件,修改了 Delight 管道加载、VAE/UNet 加载以及推理时的负提示词传递

# python/sglang/multimodal_gen/runtime/pipelines_core/stages/hunyuan3d_paint.py# 关键变更:在文件顶部的 import 中添加了 PRECISION_TO_TYPE
from sglang.multimodal_gen.utils import PRECISION_TO_TYPE# 在 _load_delight_model 中:
if local_path and os.path.exists(local_path):
    # 从配置中解析 dit_precision,默认 "fp16"
    dit_dtype = PRECISION_TO_TYPE.get(
        getattr(self.config, "dit_precision", "fp16"), torch.float16
    )
    # CPU/MPS 上回退到 fp32,因为半精度可能不受支持
    if self.device.type in ("cpu", "mps") and dit_dtype in (
        torch.float16,
        torch.bfloat16,
    ):
        dit_dtype = torch.float32
    pipeline = StableDiffusionInstructPix2PixPipeline.from_pretrained(
        local_path,
        torch_dtype=dit_dtype, # 以前是 torch.float16
        safety_checker=None,
    )
    # ...
    self._delight_pipeline = pipeline.to(self.device, dit_dtype) # 以前是 torch.float16# 在 _do_load_paint 中:
# VAE: 使用 vae_precision,默认 "fp32"
vae_dtype = PRECISION_TO_TYPE.get(
    getattr(self.config, "vae_precision", "fp32"), torch.float32
)
if self.device.type in ("cpu", "mps") and vae_dtype in (torch.float16, torch.bfloat16):
    vae_dtype = torch.float32
self.vae = self.vae.to(device=self.device, dtype=vae_dtype).eval()# UNet: 使用 dit_precision,默认 "fp16"
dit_dtype = PRECISION_TO_TYPE.get(
    getattr(self.config, "dit_precision", "fp16"), torch.float16
)
if self.device.type in ("cpu", "mps") and dit_dtype in (torch.float16, torch.bfloat16):
    dit_dtype = torch.float32
self.transformer = UNet2p5DConditionModel.from_pretrained(
    os.path.join(local_path, "unet"),
    torch_dtype=dit_dtype, # 以前是 torch.float16
).to(self.device)# 在 _run_delight 中:
image = self._delight_pipeline(
    prompt=self.config.delight_prompt,
    negative_prompt=getattr(self.config, "delight_negative_prompt", ""), # 新增:传递负提示词
    image=image,
    generator=torch.manual_seed(42),
    height=512,
    # ...
)

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

风险较低。改动集中在精度配置的读取与使用,且保留了默认行为(CUDA 下默认 fp16/bf16 不变)。CPU/MPS 回退到 fp32 是安全降级。未覆盖测试可能引入回归,但变更逻辑简单直接。

影响范围限于 Hunyuan3D 的 paint 功能。对 CUDA/ROCm 用户无行为变化;对 CPU/MPS 用户,原先因半精度而崩溃的用例现在可正常运行(回退到 fp32)。此外,delight_negative_prompt 现在生效。

缺少测试覆盖

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论