如果现有图片生成工作流只兼容其他模型的 HTTP 接口,直接切到 SeFi-Image 的风险点在于字段语义、取值范围、返回结构和错误信息都不一样。建议在业务代码与 SeFi-Image 之间加一个本地适配层,把原请求转换成 SeFi-Image 的输入,再统一返回结构和错误码。这样业务侧改动最小,适配效果靠历史样本回放验证。
适用场景:本地已有图片生成服务,想用 SeFi-Image 替换原模型,且不希望大范围改动业务代码。操作动作:记录原接口字段形状,定义适配层统一 JSON 接口,做字段映射和默认值补齐,把异常转成固定错误码,再用历史请求回放对比。验证方式:跑回放请求,检查返回字段是否完整、图片是否成功生成。风险边界:适配层只保证接口形状兼容,不保证生成图风格和效果与原模型一致。
记录现有工作流的入参和出参
先别急着写代码。把当前工作流里所有调用图片生成模型的请求抓下来,逐类记录字段。每一类请求要明确:字段名、类型、取值范围、是否必填,以及返回图片的格式(比如 base64 字符串、文件 URL,还是二进制流)。
通常原系统会有两到三种典型调用:文生图、图生图、尺寸调整。实际记录时建议用 JSON Schema 或表格列出来。至少包括下面这些信息:
- 请求路径和方式:比如
POST /generate - 必填字段:提示词、宽高、生成数量
- 可选字段:采样步数、随机种子、负面提示词
- 返回体:图片编码方式、字段名(如
image、images)、额外信息(如耗时)
同时查看 SeFi-Image 的模型输入格式。如果它只提供本地 Python 调用,就把适配层做成本地封装服务,不假设它有 HTTP API。记录这些内容是为了明确映射边界,避免后面凭感觉猜字段。
设计适配层统一接口
适配层对外提供一套固定 JSON 接口,业务侧只认这套接口,不直接感知 SeFi-Image。这样后续替换模型时,只需要改适配层内部映射。
下面是一个统一请求示例:
{
"prompt": "a cat on the moon",
"negative_prompt": "blurry",
"width": 512,
"height": 512,
"num_images": 1,
"seed": 42
}统一响应示例:
{
"code": 0,
"message": "success",
"data": {
"images": ["base64_encoded_string"],
"seed_used": 42
}
}对比原系统与 SeFi-Image 默认参数时,重点看这些差异:
- 原字段
steps可能叫num_inference_steps - 原字段
batch_size可能对应num_images - 原系统没有的字段,SeFi-Image 可能需要默认值,比如
guidance_scale - 图片返回格式:原系统可能是 URL,SeFi-Image 可能直接给张量,需要在适配层转成统一格式
建议先定义好这套统一接口,再动手写映射代码,避免边写边改。
实现参数映射和默认值补齐
适配层核心是一个映射函数。输入是原系统请求 JSON,输出是 SeFi-Image 需要的参数字典。对于缺失字段,补齐模型必需的默认值。
下面是一段通用 Python 代码骨架:
def adapt_request(raw: dict) -> dict:
# 字段映射
mapped = {
"prompt": raw.get("prompt", ""),
"negative_prompt": raw.get("negative_prompt", ""),
"width": raw.get("width", 512),
"height": raw.get("height", 512),
"num_images": raw.get("batch_size", 1),
"guidance_scale": raw.get("cfg_scale", 7.5),
"seed": raw.get("seed", -1),
}
# 步数映射,原字段可能叫 steps 或 num_steps
if "steps" in raw:
mapped["num_inference_steps"] = raw["steps"]
elif "num_steps" in raw:
mapped["num_inference_steps"] = raw["num_steps"]
else:
mapped["num_inference_steps"] = 30
# SeFi-Image 必需但原请求没有的字段,补默认值
mapped.setdefault("scheduler", "pndm")
return mapped放到哪里执行?建议把这个函数放在适配层服务的请求入口处,先解析原请求,再调用 SeFi-Image 的生成函数。执行后建议打日志,记录映射前后的完整参数,方便排查问题。
把报错转换成统一错误码
业务侧不应该直接看到模型库抛出的裸异常。适配层要捕获异常,转成固定结构,让调用方可以根据错误码做降级或重试。
可以先定义几个错误码:
1001参数错误:请求字段缺失或类型不对1002生成超时:模型推理超过设置的时间上限1003显存不足:推理设备内存不够1000未知错误
异常捕获示意:
try:
params = adapt_request(raw)
images = sefi_generate(params)
return build_success(images)
except ValueError as e:
return build_error(1001, str(e))
except TimeoutError:
return build_error(1002, "generation timeout")
except RuntimeError as e:
if "out of memory" in str(e).lower():
return build_error(1003, "GPU out of memory")
return build_error(1000, str(e))注意错误信息不要直接透传底层堆栈,只给业务侧一个可读的 message。适配层内部日志里保留完整异常,方便定位问题。
用历史样本回放验证
适配层写好后,不能只看一两个请求能通就上线。截取原系统最近一段时间内的真实请求(脱敏处理),回放到适配层,再对比结果。
做法如下:
- 从日志中抽取原始请求 JSON,去掉涉及隐私和内部的字段。
- 按调用时间顺序回放,记录每个请求的响应码、返回字段和图片是否生成成功。
- 比对原系统返回结构和适配层返回结构,确认业务侧需要用的字段都存在、类型一致。
- 抽查生成的图片,确认不是全黑或全灰,但不需要对比画质。
一个回放样本示例:
原始请求:
{
"prompt": "a castle in the sky",
"steps": 25,
"cfg_scale": 7.0
}
适配层输出:
{
"code": 0,
"data": {
"images": ["..."],
"seed_used": -1
}
}回放时如果发现某些原字段被忽略了,要回到映射函数里补上。如果返回结构里缺少业务侧依赖的字段,也要及时调整。回放全部通过后,再让业务侧联调。这样替换成本可控,后续 SeFi-Image 自身升级也不会影响业务侧代码。