Skip to content

生图修复、工作链路与承载估算

日期:2026-09-06(洛杉矶);线上配置取证为 2026-09-07 UTC。

结论与交付范围

本次针对 testing 提交 5de283a5014f1f94a65e43038dec964ee2b631c8 修复,独立分支为 codex/image-generation-reliability。改动保存在 C:/Users/peiji/Downloads/yumina-image-audit,未修改原工作目录里的其他开发内容。

交付、退款、数据库迁移、视频开放范围和配方恢复的已复现工程问题已修复并有回归验证。这是本地修复版本,尚未推送、部署到 testing 或生产,也未修改线上数据库。 下一阶段是部署 testing 后做真实 GPU 验收;当前不能据此宣布已完成公网收费上线验收。

本次修复

问题修复后的行为
先成功、后存图,前端停在空结果保存期间仍是 running;存储对象上传完成后,素材行与成功状态在同一数据库事务提交
删图被当作交付失败并退款/重建独立的 delivered_at 记录交付;删除只移除素材及历史中的图片链接,保留交付记录
重复回调/进程重启有期限的保存占用标识;仅当前占用者可提交;过期可恢复,不重复交付
通知失败变成生图失败通知独立处理,不能撤销图片或触发退款
购入蘑菇退款后变得可过期同一事务记录扣款来源;退款按来源比例回到订阅/购入余额
扣了钱但任务没创建建任务、扣余额、记录流水原子提交;任一失败全部回滚
部分退款/取消退款重试退错金额应退金额先持久化,退款标志和钱款流水同一事务提交;后台按原金额重试
删除历史可能抹去欠款批量删除前先完成待退金额;失败时保留任务记录
模型所在区域不匹配仍提交严格按可用区域交集投递,无交集拒绝;不冒险发往缺模型的区域
供应商请求无限等/健康检查拖慢列表提交 20 秒、状态/健康请求 8 秒超时;健康信息缓存并后台刷新;不盲目重试结果不明的提交
生成图绕过素材额度提交前检查,保存前按实际图片字节数在事务内再次检查,超额退款;配额错误有五种语言文案
配方恢复漏参数重置旧状态并恢复风格、垫图、强度、比例、目录、增强开关和高级参数;固定种子复用实际提示词
视频仍可进入公共模板、前端入口及新任务/新配方提交仅允许图片;保留旧视频历史兼容处理
发布 SQL 缺字段新增完整、可重跑的增量 SQL;Railway 部署前自动执行五份生图迁移,失败阻止切流量

旧记录没有保存扣款来源,无法准确反推。对尚未退款的旧失败任务采用有利于用户的兼容方式:把退款保留为不过期余额。已经错误退款的历史记录未自动补账;本次线上只读检查未发现待处理的失败/未退款任务。旧“成功但无素材”的记录不能只凭空外键判断是否曾交付,迁移不据此自动发钱。

整个生图系统如何工作

  1. 工作台收集配方。 用户输入提示词,选择六种平台风格之一,可以提供垫图,也可以调整比例、步数、CFG、采样器、种子、负面提示词。高级功能支持最多三份 LoRA、自定义基础模型、每单 1–4 张。
  2. 服务端校验。 检查登录/账号限制、图片模板、参数范围、素材和模型使用权、风格可用性、模型区域交集、余额与素材空间。每位用户最多两个排队/执行任务;提交入口还有每小时 30 次的用户限流。它们不是全站 GPU 容量保证。
  3. 可选的提示词增强。 通过 OpenRouter 调用文本模型,把自然语言转成模型适用的英文标签或描述;原文和改写都会经过现有文字规则检查。增强失败可回退原提示词;用户可关闭增强。它不负责生成像素。
  4. 服务端定价与扣款。 默认动漫简单模式单张 10 蘑菇,其余五种平台风格简单模式单张 20 蘑菇。高级模式按像素、步数、批量重新计算,加 LoRA/自定义模型费用。价格以服务端为准,任务、扣款和来源流水一起写入 PostgreSQL。
  5. RunPod GPU 执行 ComfyUI。 Yumina 拼装固定工作流,把配方交给有相应模型的区域。默认模型为 Animagine XL 4.0,默认 832×1216、28 步。平台其他模型提前同步到区域磁盘;自定义模型另有导入、同步及临时同步机器回收流程。
  6. 图片落到素材库。 完成回调携带每单独有凭证;后台查询作为回调丢失的补偿。Yumina 下载结果、写入自己的对象存储,核验额度后提交素材和成功状态。前端每 5 秒刷新未完成任务,完成后展示、通知和刷新素材库。
  7. 异常结算。 失败按记录退款;正在执行时用户取消退 50%,尚未执行时取消全退。批量缺图按缺失图片的边际价格退款,不退已经承担的模型固定费用。后台约每 2 分钟检查最多 50 个活动任务及 50 个待退款任务,总任务时限为 30 分钟。

这里的 GPU 与聊天/网页服务是分离的。增加网页服务器副本不会直接增加生图速度。

当前真实 GPU 配置

以下来自 RunPod 管理 API 的只读配置,不是根据代码猜测;每实例一块 GPU。

区域配置的最少/最多实例可选显卡平台模型范围
EU-CZ-10 / 33090、4090、5090默认动漫及五种附加平台风格
US-IL-10 / 24090、L40S、5090默认动漫;五种附加平台模型未登记同步到这里
EU-RO-10 / 34090、5090默认动漫及五种附加平台风格

合计配置上限 8 个 GPU 实例,非默认平台风格最多使用欧洲的 6 个,自定义模型还取决于其同步区域交集。不是承诺任何时刻都能租到 8 块卡;不同型号、模型切换与批量大小都会影响速度。

三处均开启 FlashBoot,空闲回收约 60 秒、队列等待触发扩容阈值 4 秒、单次 GPU 执行超时 900 秒。最少实例为 0,意味着没有保证常驻预热的执行容量;另有欧洲各 3 个 standby 配置,不应把 standby 当作额外的同时执行实例。最大实例、最少实例与扩容规则的含义见 RunPod 端点配置

能承受多少人

目前没有有效的真实压测,不能保证“支持 N 人”。 线上仅留存 6 单图片成功记录,平均端到端耗时约 146 秒,且都属于默认风格,未覆盖垫图、多张批量及其他平台风格。端到端耗时包含排队和冷启动,不能当作纯 GPU 推理时间。

用每单一张、平均占用一个 worker、70% 利用率预留突发余量作为规划假设:

可规划单量/小时 ≈ 可用 worker 数 × 3600 ÷ 平均 worker 占用秒数 × 0.7

假设每单实际占用 worker8 worker,全区域6 worker,欧洲风格每人每 5 分钟发一单时,全区域持续活跃人数
60 秒336 单/小时252 单/小时约 28 人
120 秒168 单/小时126 单/小时约 14 人
180 秒112 单/小时84 单/小时约 9 人

RunPod 也按到达率乘任务时长估算并发 worker,并区分排队/冷启动与执行时间;以上 70% 是我们的规划假设,不是 RunPod 的保证。RunPod 性能与容量说明

如果暂时用 146 秒这个历史端到端平均数作保守参考,得出约 138 单/小时(8 worker)或 104 单/小时(6 worker)。因为样本极少且非纯执行时长,建议只拿 100–150 单/小时、约 8–12 名每 5 分钟持续发单的用户作为初始灰度预算,不能把它当承诺。批量四张及频繁自定义模型切换不能套用这个单张估算。

用户可以多于 GPU 数量,但会排队;“同时在线 100 人”与“100 人持续点生图”完全不同。注册人数、在线浏览/聊天人数还取决于 Railway、数据库、聊天模型限额等,本次没有整站压测,不能从这八个实例推导整站人数上限。

最值得继续优化的事项

  1. 先测真实工作负载,再扩容。 至少覆盖六种风格、垫图、1/4 张批量、模型切换;用 1/4/8/16 并发阶梯记录排队、冷启动、纯执行、落盘的 p50/p95、成功率、退款率和每张实际成本。图像质量需单独验收。
  2. 减少冷启动和换模型。 首先评估欧洲常驻一台热门风格 worker,或延长空闲回收时间;低频风格仍按需启动。常驻会增加空闲成本,本次没有改云端计费配置。现有容器还支持视频,单独制作固定版本的图片 worker 可以减少依赖与冷启动负担。
  3. 增加全局/区域排队保护。 当前只有用户限流,没有按区域估算等待时长的全局入队上限。高峰要在扣费前告知预计等待,队列过深则拒绝或延后;默认动漫、风格切换和昂贵自定义模型应有不同预算。
  4. 将保存和补偿交给持久后台队列。 目前保存仍在请求/补偿进程中执行,已有占用标识和恢复,但横向扩容后应有可续租的任务队列。补偿扫描改为有限并发与公平轮转,避免前 50 个长任务延后后面的任务;清理进程突然死亡后留下的无主对象。
  5. 补充端到端提交幂等与成本监控。 现在可以防重复交付和重复退款,但“供应商已接单、响应丢失”仍可能造成平台承担一个无法跟踪的 GPU 任务。需要请求幂等键/可靠投递记录、区域队列告警、欠退款告警和低余额/每日 GPU 花费上限。
  6. 统一素材额度与内容处理。 生图已计入额度,但普通上传的 sizeBytes 仍由客户端报告,后续应全站以存储实测字节计费并统一锁。现有内容检查以文字规则为主,垫图和生成结果没有图片分类检测;这部分仍是公开开放范围和内容处理能力的缺口,本次未新增检测服务。

验证与发布步骤

  • 隔离回归使用内存 PostgreSQL 执行真实 SQL、真实扣/退款及 hash 流水实现,存储、通知、供应商注入故障;也调用实际 Hono 提交接口验证视频拒绝和图片扣款。不是只检查代码文本。
  • 已验证建单回滚、混合余额退款、保存过程状态、重复回调、通知失败、删除单图/批量第一张、配额、部分退款重试、取消退款重试、保存占用超时、区域限制、提交超时不重发、配方恢复。
  • 全仓构建 5/5、类型检查 8/8 通过;服务端生图/相关余额测试 79 项、共享定价 5 项与前端配方 3 项通过,共 87 项。构建仍有既有的大体积前端包提示。未打开浏览器、未用真实 GPU 进行新一轮出图或负载测试。
  • 发布先经过 prepare-generation.mjs:五份 SQL 在同一事务中执行,限时等待数据库锁,失败不切流量;可重复运行。
  • testing 和 main 已明显分叉,生产仍缺生图配置和平台模型记录。生产发布需要有范围地移植、补齐配置/模型并验收,不能直接合并整个 testing。
  • 回滚代码不删除新增列、交付记录或退款记录。因为旧生图代码仍有删图误退款缺陷,不能把旧逻辑当作安全的生图回滚;必要时先关闭生图入口,并继续结算已经接收的任务。