Stable Diffusion 3.5 接入统一绘图 API 时的请求参数映射表

文章导读
接入统一绘图 API 时,团队最容易撞上的问题不是模型效果,而是参数口径不一致。Stable Diffusion 3.5 的请求体与自家统一规范里的字段名、取值范围、默认规则往往对不上,导致 prompt 传过去了但采样参数空转,或者种子类型错误直接报 422。下面给出一张可复制的映射表模板和转换逻辑,让接入工作从“对着文档猜”变成“对着代码改”。
📋 目录
  1. A 先画统一绘图 API 与 SD3.5 的字段差异
  2. B 写一个参数转换函数兼容不同调用方
  3. C 映射后如何校验参数合法性与默认值
  4. D 将 SD3.5 返回错误映射为统一错误结构
A A

接入统一绘图 API 时,团队最容易撞上的问题不是模型效果,而是参数口径不一致。Stable Diffusion 3.5 的请求体与自家统一规范里的字段名、取值范围、默认规则往往对不上,导致 prompt 传过去了但采样参数空转,或者种子类型错误直接报 422。下面给出一张可复制的映射表模板和转换逻辑,让接入工作从“对着文档猜”变成“对着代码改”。

本文提供统一绘图 API 到 Stable Diffusion 3.5 的请求参数映射表模板、Python 转换骨架、校验规则与错误映射结构。适用于已有统一 API 规范、正在接入 SD3.5 的团队。操作动作是:先比对字段,再套用转换函数,最后验证边界。注意:SD3.5 部署方式不同,字段名可能有差异,需以实际网关或推理服务为准。

先画统一绘图 API 与 SD3.5 的字段差异

统一绘图 API 通常按业务语言定义参数,SD3.5 推理服务则按模型实现定义参数。直接透传不是不行,但会让调用方被迫了解 SD3.5 的内部细节。建议先列一张映射表,把字段分成三类:直接映射、名称转换、值域转换。下面是一张可参考的模板,字段名需要结合你的网关实际配置确认。

统一 API 字段SD3.5 常见字段映射类型与处理建议
promptprompt直接映射
negative_promptnegative_prompt直接映射
width / heightwidth / height名称相同,值域不同,SD3.5 通常要求是 16 的倍数
stepsnum_inference_steps名称转换,需做范围校验
seedseed类型强转 int,SD3.5 不支持浮点种子
cfg_scaleguidance_scale名称转换,建议保留 1-2 位小数
schedulerscheduler值域转换,统一 API 的枚举值与 SD3.5 不完全一致
batch_sizenum_images_per_prompt名称转换,需确认 SD3.5 服务是否允许一次生成多张

注意:这只是一个起点。如果你的统一 API 里还有 sampler、clip_skip、controlnet 等字段,映射前先确认 SD3.5 部署是否开放了这些参数。未开放的字段不要放进请求体,否则可能被忽略或报错。

Stable Diffusion 3.5 接入统一绘图 API 时的请求参数映射表

写一个参数转换函数兼容不同调用方

映射表最终要落到代码上。建议在网关层写一个独立的转换函数,输入统一定义的请求字典,输出 SD3.5 格式的请求体。这样前端和上游系统只对准统一 API,不感知 SD3.5 的字段名。

def convert_unified_to_sd35(uni: dict) -> dict:
    # 基线映射:统一字段名 -> SD3.5 字段名
    name_map = {
        'prompt': 'prompt',
        'negative_prompt': 'negative_prompt',
        'steps': 'num_inference_steps',
        'cfg_scale': 'guidance_scale',
        'scheduler': 'scheduler',
        'batch_size': 'num_images_per_prompt',
    }
    sd35 = {}
    for unified_key, sd_key in name_map.items():
        if unified_key in uni:
            sd35[sd_key] = uni[unified_key]
    # 直接映射的宽高和种子
    if 'width' in uni:
        sd35['width'] = int(uni['width'])
    if 'height' in uni:
        sd35['height'] = int(uni['height'])
    if 'seed' in uni:
        sd35['seed'] = int(uni['seed'])
    return sd35

这个函数只做名称和类型转换,不负责校验。配合第三段的校验逻辑使用,可以避免把非法参数直接传给 SD3.5 推理服务。

Stable Diffusion 3.5 接入统一绘图 API 时的请求参数映射表

映射后如何校验参数合法性与默认值

SD3.5 对参数范围比较敏感,比如 steps 太小可能出图质量差,太大又拖慢响应。统一 API 的调用方不一定了解这些边界,所以建议在转换后、请求发出前做一次校验,并填充默认值。

DEFAULTS = {'steps': 30, 'guidance_scale': 4.5, 'num_images_per_prompt': 1}

def sanitize_sd35_params(p: dict) -> dict:
    for k, v in DEFAULTS.items():
        p.setdefault(k, v)

    # 宽高校验:按常见池化倍数,限制为 16 的整数倍
    for dim in ('width', 'height'):
        if dim in p:
            try:
                p[dim] = int(p[dim])
            except (TypeError, ValueError):
                raise ValueError(f'{dim} 必须是整数')
            if p[dim] % 16 != 0:
                # 若你的 SD3.5 服务允许非 16 倍,可移除或改为警告
                p[dim] = (p[dim] // 16) * 16  # 向下取整到 16 的倍数

    # steps 范围:示例 1-50,可按模型能力调整
    if p.get('steps') is not None:
        p['steps'] = max(1, min(int(p['steps']), 50))

    return p

校验逻辑放在网关层比较合适。这样入口统一收口,错误类型也更容易归类。如果 SD3.5 服务自身对范围有严格要求,比如 steps 必须大于 4,需要在上面的范围上再收紧。

Stable Diffusion 3.5 接入统一绘图 API 时的请求参数映射表

将 SD3.5 返回错误映射为统一错误结构

SD3.5 返回的错误格式不一定和你的统一 API 一致,可能是 HTTP 状态码加原始字符串,也可能带内部字段。为了让前端和上游系统拿到一致的异常信息,建议在网关层捕获所有 SD3.5 异常,并转换成统一 JSON 错误结构。

UNIFIED_ERROR = {
    'code': '55040',       # 自定义业务码,这里只是示例
    'message': 'SD3.5 请求失败',
    'details': {},
    'request_id': '',
}

def map_sd35_error(e: Exception, request_id: str) -> dict:
    err = UNIFIED_ERROR.copy()
    err['request_id'] = request_id
    if hasattr(e, 'status_code'):
        status = e.status_code
        if status in (400, 422):
            err['code'] = '55041'  # 参数错误
            err['message'] = 'SD3.5 参数校验未通过'
        elif status == 504:
            err['code'] = '55042'  # 超时
            err['message'] = 'SD3.5 推理服务超时'
        else:
            err['code'] = '55043'
            err['message'] = f'SD3.5 服务返回异常状态 {status}'
    else:
        err['code'] = '55044'
        err['message'] = f'SD3.5 调用异常: {str(e)}'
    err['details'] = {'source': 'sd35'}
    return err

这个结构里的 code 只是占位示例,你可以按自己的错误码体系替换。关键是所有 SD3.5 相关的错误都统一走这一层,不要让原始堆栈直接透出到业务响应里。