033 文生图应用Stable Diffusion API调用与本地部署昨天半夜被一个bug卡到凌晨三点——调用Stable Diffusion API生成图片返回的base64字符串死活解析不出来。debug到最后发现是响应体里多了个换行符Python的base64.b64decode直接报错。这种破事在AI应用开发里太常见了今天就把Stable Diffusion从API调用到本地部署的坑都填上。先搞定API调用别被官方文档带偏大多数新手会直接去HuggingFace或者Replicate上找SD的API文档照着示例写代码。但实际生产环境里你大概率用的是别人封装好的服务比如公司内部部署的SD WebUI或者ComfyUI。我这边用的是SD WebUI自带的API接口默认在http://localhost:7860/sdapi/v1/txt2img。注意这个路径网上有些老教程写的是/sdapi/v1/txt2img但新版本SD WebUI的API前缀变了直接写会404。importrequestsimportbase64fromPILimportImageimportio# 这里踩过坑payload的key必须和SD WebUI API文档完全一致# 别自己瞎起名字比如把prompt写成text或者inputpayload{prompt:a cute cat wearing a hat, digital art, high quality,negative_prompt:ugly, blurry, low quality,# 这个参数不加的话出图质量会飘steps:20,# 别写太大20步足够写50步显卡要冒烟width:512,height:512,cfg_scale:7,# 7-9之间比较稳调太高图片会过饱和sampler_name:Euler a,# 别用DDIMEuler a出图快且稳定batch_size:1# 一次生成一张多了容易OOM}responserequests.post(http://localhost:7860/sdapi/v1/txt2img,jsonpayload,timeout60# 不加timeout的话网络卡住就死锁了)# 这里有个巨坑response.json()里的images字段是列表# 但如果你只生成一张图它也是个列表别直接取[0]ifresponse.status_code200:resultresponse.json()# 注意base64字符串可能包含换行符需要strip掉# 我昨天就是被这个坑的SD WebUI返回的base64末尾有个\nimg_database64.b64decode(result[images][0].strip())imgImage.open(io.BytesIO(img_data))img.save(output.png)print(图片已保存路径output.png)else:print(f请求失败状态码{response.status_code})print(f错误信息{response.text})# 这个一定要打印SD的错误信息很有用本地部署别被显卡驱动劝退API调用只是开胃菜真正要搞生产环境你得自己部署SD。这里说一个血泪教训别用最新版Python。SD WebUI官方推荐Python 3.10.6你用3.11或者3.12会有一堆依赖冲突。环境搭建的坑# 别直接用pip install会死得很惨# 先创建虚拟环境Python版本必须3.10.6conda create-nsdpython3.10.6 conda activate sd# 克隆SD WebUI仓库注意分支gitclone https://github.com/AUTOMATIC1111/stable-diffusion-webui.gitcdstable-diffusion-webui# 这里有个坑直接运行webui.sh会下载一堆依赖# 但国内网络环境经常超时建议先配置镜像源# 在webui.sh里找到pip install的地方改成# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ...# 或者手动安装torch别让脚本自动装pipinstalltorch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118模型下载的玄学SD WebUI启动后会自动下载一些基础模型但核心的Stable Diffusion模型需要你自己放。去HuggingFace下载v1-5-pruned-emaonly.safetensors放到models/Stable-diffusion/目录下。别下错了版本safetensors格式比ckpt格式安全不会执行恶意代码。而且pruned-emaonly版本体积小约2GB推理速度快。# 手动下载模型别用webui自带的下载功能经常断# 推荐用aria2c多线程下载aria2c-x4-s4https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors启动参数调优# 别直接运行webui.sh加参数优化性能# --medvram 是给8GB显存显卡用的12GB以上可以不加# --no-half 别加会降低性能# --api 必须加否则无法通过API调用python launch.py--medvram--api--listen--port7860--listen参数让服务监听所有网络接口这样局域网内其他机器也能调用。但注意安全别暴露到公网除非你加了认证。进阶批量生成与异步处理单张生成太慢生产环境需要批量处理。这里有个优化技巧不要并发请求SD WebUI它内部是单线程处理的。正确的做法是修改batch_size参数。# 批量生成一次生成4张payload{prompt:a cute cat wearing a hat,batch_size:4,# 一次生成4张比并发4次请求快得多steps:20,width:512,height:512}responserequests.post(url,jsonpayload)resultresponse.json()fori,img_b64inenumerate(result[images]):img_database64.b64decode(img_b64.strip())withopen(foutput_{i}.png,wb)asf:f.write(img_data)如果生成任务特别多建议用消息队列比如Redis Celery做异步处理。SD WebUI本身不支持并发但你可以部署多个实例每个实例绑定不同的GPU。踩坑总结Python版本必须3.10.6别问为什么问就是依赖冲突base64解码前一定要strip()SD WebUI返回的字符串末尾有换行符batch_size比并发请求更高效SD内部是串行处理的模型文件用safetensors格式别用ckpt安全第一启动参数加–api和–medvram前者是API调用必须后者是显存不够时的救命稻草最后说个个人经验别在生产环境用SD WebUI的默认配置。它的--gradio-auth参数可以加HTTP基本认证但不够安全。建议用Nginx反向代理加个简单的Token验证。或者直接用FastAPI自己封装一层把SD WebUI当后端引擎用这样控制更灵活。明天准备写ControlNet的API调用那个坑更多尤其是姿态检测和深度图预处理搞不好就出鬼图。