news 2026/9/10 1:25:32

Diffusers 混合推理 API 参考:`remote_encode` 与 `remote_decode` 远程 VAE 编解码实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Diffusers 混合推理 API 参考:`remote_encode` 与 `remote_decode` 远程 VAE 编解码实战指南

Diffusers 混合推理 API 参考:remote_encoderemote_decode远程 VAE 编解码实战指南

【免费下载链接】diffusers🤗 Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers

混合推理(Hybrid Inference)是 Diffusers 提供的一项实验性能力,它把 VAE 编码、解码过程卸载到远程推理端点执行,从而让本地仅需加载扩散模型主体即可完成完整推理流程。本文以 api_reference.md 为骨架,结合 remote_utils.py 的源码 docstring 与 tests/remote 下的测试用例,系统讲解remote_encoderemote_decode两个公开 API 的完整参数语义、底层实现与实战用法,读完即可在低显存环境下跑通"编码 → 生成 → 解码"的完整链路。

一、混合推理 API 概述

1.1 为什么需要混合推理

扩散模型推理的显存压力通常来自两部分:UNet/Transformer 主干与 VAE。混合推理将占用可观显存、且与主干计算解耦的 VAE 部分转移到远程端点,本地只需要承担文本编码器与 UNet/Transformer 的推理负载,显著降低硬件门槛。其核心优势(见 overview.md)包括:

  • 降低要求:无需昂贵硬件即可访问强大模型;
  • 质量无损:解码、编码仍由对应模型的官方 VAE 完成,不牺牲输出质量;
  • 成本友好:当前以免费 Pilot 形式提供;
  • 开发者友好:只需一次简单的 HTTP 请求即可获得响应。

整个功能由 Hugging Face Inference Endpoints 支撑,对应端点常量集中定义在 constants.py。

1.2 API 入口

api_reference.md通过 autodoc 指令从源码 docstring 自动生成参考文档,公开 API 位于diffusers.utils.remote_utils模块(模块导出处),共两个函数:

函数作用返回值
remote_encode将图像/视频远程编码为潜在表示(latent)torch.Tensor
remote_decode将潜在表示远程解码为图像/视频Image.Image/list[Image.Image]/bytes/torch.Tensor

调用方式:

from diffusers.utils.remote_utils import remote_decode, remote_encode

二、remote_encode:远程 VAE 编码

remote_encode适用于训练、图生图、图生视频等场景——把图像或视频转换为潜在表示。其函数签名为:

def remote_encode( endpoint: str, image: "torch.Tensor" | Image.Image, scaling_factor: float | None = None, shift_factor: float | None = None, ) -> "torch.Tensor":

2.1 参数说明

参数类型必填说明
endpointstr远程编码端点的 URL。不同模型对应不同端点,见 constants.py 中的ENCODE_ENDPOINT_*常量
imagetorch.TensorPIL.Image.Image待编码的图像。传入torch.Tensor时需为float16/bfloat16等内存布局连续的张量;传入 PIL 图像时会自动序列化为 PNG 字节流发送
scaling_factorfloat缩放因子。传入后端点会在编码过程中自动应用缩放(等价于latents * scaling_factor的逆操作)。若为None,则输入必须已由调用方完成缩放
shift_factorfloat平移因子。传入后端点自动应用平移(等价于latents - shift_factor的逆操作)。若为None,则输入必须已由调用方完成平移

2.2 基本用法示例

以 Flux 模型为例,将一张图像远程编码为潜在表示:

from diffusers import FluxPipeline from diffusers.utils import load_image from diffusers.utils.remote_utils import remote_encode pipeline = FluxPipeline.from_pretrained( "black-forest-labs/FLUX.1-schnell", dtype=torch.float16, vae=None, # 关键:不加载本地 VAE device_map="cuda", # 也可用 "mps"、"xpu"、"cpu" ) init_image = load_image("path/to/astronaut.jpg") init_image = init_image.resize((768, 512)) init_latent = remote_encode( endpoint="https://ptccx55jz97f9zgo.us-east-1.aws.endpoints.huggingface.cloud/", image=init_image, scaling_factor=0.3611, # Flux 的缩放因子 shift_factor=0.1159, # Flux 的平移因子 )

提示:remote_encode使用的 Flux 编码端点与解码端点不同,编码端点在 constants.py 中定义为ENCODE_ENDPOINT_FLUX

三、remote_decode:远程 VAE 解码

remote_decode将扩散模型输出的潜在表示转换回图像或视频,是混合推理最常用的 API。其函数签名为:

def remote_decode( endpoint: str, tensor: "torch.Tensor", processor: "VaeImageProcessor" | "VideoProcessor" | None = None, do_scaling: bool = True, scaling_factor: float | None = None, shift_factor: float | None = None, output_type: Literal["mp4", "pil", "pt"] = "pil", return_type: Literal["mp4", "pil", "pt"] = "pil", image_format: Literal["png", "jpg"] = "jpg", partial_postprocess: bool = False, input_tensor_type: Literal["binary"] = "binary", output_tensor_type: Literal["binary"] = "binary", height: int | None = None, width: int | None = None, ) -> Image.Image | list[Image.Image] | bytes | "torch.Tensor":

3.1 核心参数详解

输入相关
参数类型默认值说明
endpointstr远程解码端点 URL,见 constants.py 的DECODE_ENDPOINT_*常量
tensortorch.Tensor待解码的潜在表示张量。序列化在本地 CPU 完成,本地设备不影响结果
processorVaeImageProcessor/VideoProcessorNone图像/视频后处理器。当return_type="pt"且需要图像输出、或视频模型返回pil时需要传入
height/widthintNonepacked latents(如 Flux 打包格式)必须显式传入,用于还原空间尺寸;普通[1, C, H, W]布局无需传入
缩放与平移(Scaling / Shift)
参数类型默认值说明
do_scalingboolTrue已弃用(计划在 1.0.0 移除)。应改用显式传入scaling_factor/shift_factor。为True时缩放(如latents / vae.config.scaling_factor)在远端执行;为False时输入必须已应用缩放
scaling_factorfloatNone传入后在远端自动应用缩放。若为None,输入必须已由调用方完成缩放
shift_factorfloatNone传入后在远端自动应用平移(如latents + vae.config.shift_factor)。若为None,输入必须已由调用方完成平移
输出控制
参数类型默认值说明
output_type"mp4"/"pil"/"pt""pil"端点的输出类型:"mp4"仅视频模型支持,端点返回视频bytes"pil"图像模型返回image_format编码的图像字节,视频模型返回已部分后处理的torch.Tensor"pt"图像与视频均支持,端点返回torch.Tensor
return_type"mp4"/"pil"/"pt""pil"函数的返回类型:"mp4"返回视频bytes"pil"返回PIL.Image.Image"pt"返回torch.Tensor
image_format"png"/"jpg""jpg"output_type="pil"时生效,指定端点返回 jpg 还是 png
partial_postprocessboolFalseoutput_type="pt"时生效:False时返回未反归一化的float16/bfloat16张量;True时返回已反归一化的uint8张量
input_tensor_type/output_tensor_type"binary""binary"张量传输格式。"base64"已被弃用,统一使用"binary"

3.2output_typereturn_type的四种组合

两个参数独立控制"端点侧输出"与"本地侧返回",组合后可覆盖几乎所有使用场景:

  • output_type="pil"+return_type="pil":端点返回图片字节,本地直接打开为 PIL 图像(无需processor);
  • output_type="pt"+return_type="pil":端点返回张量,本地用processor后处理为 PIL 图像(partial_postprocess=True时可不传processor);
  • output_type="pt"+return_type="pt":端到端张量传输,适合对接第三方后处理代码(不要求processor);
  • output_type="mp4"+return_type="mp4":视频字节流直通,本地写文件即可。

3.3 官方推荐

源码 docstring 中给出了三条传输方案建议:

  • "pt"+partial_postprocess=True最小传输体积下保持完整质量(uint8 已反归一化);
  • "pt"+partial_postprocess=False与第三方代码兼容性最好(保留浮点张量);
  • "pil"+image_format="jpg"整体传输体积最小

3.4 解码实战示例(Flux)

Flux 的 latent 是打包(packed)布局,解码时必须显式传入heightwidth

from diffusers import FluxPipeline from diffusers.utils.remote_utils import remote_decode pipeline = FluxPipeline.from_pretrained( "black-forest-labs/FLUX.1-schnell", dtype=torch.bfloat16, vae=None, device_map="cuda", ) prompt = "A photorealistic Apollo-era photograph of a cat astronaut on the Moon..." latent = pipeline( prompt=prompt, guidance_scale=0.0, num_inference_steps=4, output_type="latent", # 关键:管线输出 latent 而非图像 ).images image = remote_decode( endpoint="https://whhx50ex1aryqvw6.us-east-1.aws.endpoints.huggingface.cloud/", tensor=latent, height=1024, width=1024, scaling_factor=0.3611, shift_factor=0.1159, ) image.save("image.jpg")

3.5 视频解码实战示例(HunyuanVideo)

视频模型的远端解码支持output_type="mp4",直接获得视频字节:

import torch from diffusers import HunyuanVideoPipeline, HunyuanVideoTransformer3DModel from diffusers.utils.remote_utils import remote_decode transformer = HunyuanVideoTransformer3DModel.from_pretrained( "hunyuanvideo-community/HunyuanVideo", subfolder="transformer", dtype=torch.bfloat16 ) pipeline = HunyuanVideoPipeline.from_pretrained( "hunyuanvideo-community/HunyuanVideo", transformer=transformer, vae=None, dtype=torch.float16, device_map="cuda", ) latent = pipeline( prompt="A cat walks on the grass, realistic", height=320, width=512, num_frames=61, num_inference_steps=30, output_type="latent", ).frames video = remote_decode( endpoint="https://o7ywnmrahorts457.us-east-1.aws.endpoints.huggingface.cloud/", tensor=latent, output_type="mp4", ) if isinstance(video, bytes): with open("video.mp4", "wb") as f: f.write(video)

四、模型缩放/平移因子速查

scaling_factorshift_factor因模型而异,源码 docstring 与 tests/remote/test_remote_decode.py 中给出了各模型的权威取值:

模型scaling_factorshift_factor解码端点常量备注
Stable Diffusion v10.18215DECODE_ENDPOINT_SD_V1参考stabilityai/sd-vae-ft-mse
Stable Diffusion XL0.13025DECODE_ENDPOINT_SD_XL参考madebyollin/sdxl-vae-fp16-fix
Flux0.36110.1159DECODE_ENDPOINT_FLUXlatent 为 packed 布局,解码需传height/width;测试中 dtype 为bfloat16
HunyuanVideo0.476986DECODE_ENDPOINT_HUNYUAN_VIDEO仅支持解码;dtype 为float16

注意:以上数值必须与所选端点对应的 VAE 模型严格匹配。若scaling_factor/shift_factorNone,则调用方必须在发送前自行完成缩放与平移(测试用例test_no_scaling正是先本地tensor / scaling_factortensor + shift_factor再调用)。

五、底层实现剖析

remote_utils.py的每个公开函数都由"输入校验 → 请求准备 → HTTP 传输 → 响应后处理"四个阶段组成,理解这一链路有助于排查问题。

5.1 编码链路(prepare_encodepostprocess_encode

  • check_inputs_encode:参数校验占位(当前为空实现);
  • prepare_encode:若输入是torch.Tensor,通过safetensors.torch._to_ndarray(image.contiguous())取出底层 numpy 数组再转字节,同时把shapedtype写入请求参数;若输入是 PIL 图像,则保存为 PNG 字节流。缩放/平移因子也会随请求参数一并发送;
  • HTTP 传输:requests.post(endpoint, **kwargs),端点异常时抛出RuntimeError(response.json())
  • postprocess_encode:从响应头读取shapedtype,用torch.frombuffer在本地零拷贝重建torch.Tensor

5.2 解码链路(prepare_decodepostprocess_decode

解码链路多了内容协商逻辑:

  • prepare_decode依据参数组合设置Content-Type: tensor/binaryAccept头——"pil"+ jpg 时为image/jpeg,png 时为image/png"mp4"时为text/plain,其余为tensor/binaryshapedtypescaling_factorshift_factor等随请求发送;
  • postprocess_decodeoutput_type分支处理响应:
    • "pt":从字节流重建张量;partial_postprocess=False且传processor时,经由processor.postprocess/postprocess_video得到 PIL 图像;
    • "pil"且无processorImage.open(io.BytesIO(...))直接打开端点返回的图片字节,并通过 detect_image_type(依据 JPEG/PNG/GIF/BMP 魔数)还原图片格式;
    • "pil"且有processor:将float张量permute后乘以 255 转为uint8图像数组;
    • "mp4":原样返回视频字节。

5.3 张量 dtype 映射

端到端传输使用 DTYPE_MAP 在字符串与torch.dtype之间映射,覆盖float16float32bfloat16uint8四种,这也是output_type="pt"时能无损还原张量的关键。

六、测试验证与限制说明

6.1 测试覆盖

仓库在 tests/remote/test_remote_decode.py 与 tests/remote/test_remote_encode.py 中对上述 API 进行了系统性验证:

  • 组合覆盖test_output_type_pttest_output_type_piltest_output_type_pt_partial_postprocesstest_output_type_pt_return_type_pttest_output_type_mp4等用例逐一验证各输出组合;
  • 无缩放路径test_no_scaling验证调用方本地预缩放后传入do_scaling=False的兼容路径;
  • 弃用告警test_do_scaling_deprecationtest_input_tensor_type_base64_deprecation验证do_scalingbase64传输的FutureWarning
  • 多分辨率test_multi_res覆盖 320~2048 共 12 档分辨率下的编码→解码往返;
  • 确定性:测试在 CPU 上以固定种子(manual_seed(13))生成 latent 再搬运到目标设备,以保证参考切片可复现。

这些测试均标记为@slow,命中真实 Inference Endpoints,不属于常规 CI 契约。

6.2 使用限制与注意事项

  • 实验性功能:混合推理当前处于实验阶段,接口与端点随时可能调整,反馈可通过项目 Issue 提交;
  • 端点可用性:以仓库当前状态为准,编码端点(ENCODE_ENDPOINT_*)曾出现下架并返回404 NOT_FOUND的情况(test_remote_encode.py 中的xfail标记即为此记录),实际使用时请以端点当前状态为准;
  • packed latents 必传尺寸:解码 Flux 等打包格式 latent 时,漏传height/width会直接触发ValueError: 'height' and 'width' required for packed latents'(见 check_inputs_decode);
  • 管线侧配合:使用混合推理时,管线需设置vae=None且生成时传output_type="latent",本地不再执行 VAE 相关计算。

七、完整链路示例:图生图

综合编码与解码,一个完整的"远程编码 → 本地生成 → 远程解码"流程如下(对应 vae_encode.md 中的生成示例):

import torch from diffusers import StableDiffusionImg2ImgPipeline from diffusers.utils import load_image from diffusers.utils.remote_utils import remote_decode, remote_encode pipe = StableDiffusionImg2ImgPipeline.from_pretrained( "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16", vae=None, ).to("cuda") init_image = load_image("path/to/sketch-mountains-input.jpg") init_image = init_image.resize((768, 512)) # 1. 远程编码:图像 → latent init_latent = remote_encode( endpoint="https://qc6479g0aac6qwy9.us-east-1.aws.endpoints.huggingface.cloud/", image=init_image, scaling_factor=0.18215, ) # 2. 本地生成:latent → 新的 latent prompt = "A fantasy landscape, trending on artstation" latent = pipe( prompt=prompt, image=init_latent, strength=0.75, output_type="latent", ).images # 3. 远程解码:latent → 图像 image = remote_decode( endpoint="https://q1bj3bpq6kzilnsu.us-east-1.aws.endpoints.huggingface.cloud/", tensor=latent, scaling_factor=0.18215, ) image.save("fantasy_landscape.jpg")

八、性能参考(编码显存对比)

混合推理的价值在显存对比中最为直观。根据 vae_encode.md 中记录的 SD v1 编码实测数据(VAE 本地运行),2048×2048 分辨率在 RTX 3070 上会占用约 96% 显存、RTX 3080 上约 86.7%,而采用分块(tiled)编码后内存可压至约 8.5%~10.7%——但分块会增加耗时并影响质量。混合推理把 VAE 完全移出本地,等效于将这部分显存占用归零,从而为文本编码器与 UNet/Transformer 释放空间,这正是"无需昂贵硬件即可运行大模型"的机制基础。

对于更进一步的批量解码吞吐优化,可参考 overview.md 中基于queue.Queue+ 后台线程的解码队列模式:在解码当前 latent 的同时排队下一个 prompt 的生成请求,实现生成与解码流水线化。


延伸阅读:混合推理的整体概念与模型支持见 overview.md,编码入门与内存基准见 vae_encode.md,完整实现源码见 remote_utils.py,端点常量见 constants.py。

【免费下载链接】diffusers🤗 Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 1:23:31

SAP年结必看:FAGLGVTR与F.16总账余额结转实操与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 1:20:47

基于Django+Vue3的校园租房系统全栈开发实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华