先把工作流参数锁进配置再谈复现——ArtCraft 可控出图的搭法

文章导读
一套 ArtCraft 工作流如果只在界面里点参数,关掉页面就等于丢了一次实验,团队里也没人能说清哪一组值才是有效的。更稳的顺序是先把参数分成“必须锁死”和“允许变化”两类,固定项写进一份带版本名的配置文件,然后用固定种子跑一次基线、按存档重跑一次做比对。判断复现是否成立的标准很直接:同一份配置、同一入口、同一输出目录规则下,两次出图的尺寸、构图、色调和细节都能对得上。
📋 目录
  1. Ⅰ 列出当前工作流里全部可调参数并分成固定项与随机项
  2. Ⅱ 把固定项写进工作流配置并给这份配置起版本名
  3. Ⅲ 用固定种子跑一次并留下输出记录
  4. Ⅳ 按存档配置重跑第二次,比对两次输出
  5. Ⅴ 把随机项集中到单独一处,说明允许变化的边界
A A

一套 ArtCraft 工作流如果只在界面里点参数,关掉页面就等于丢了一次实验,团队里也没人能说清哪一组值才是有效的。更稳的顺序是先把参数分成“必须锁死”和“允许变化”两类,固定项写进一份带版本名的配置文件,然后用固定种子跑一次基线、按存档重跑一次做比对。判断复现是否成立的标准很直接:同一份配置、同一入口、同一输出目录规则下,两次出图的尺寸、构图、色调和细节都能对得上。

复现的起点是把参数落盘,而不是调提示词。建议先导出当前工作流的完整参数,按“影响画风与结构的固定项”和“只影响批次内变化的随机项”分开,固定项写进 workflows/<流程>/<版本名>/config.yaml,随机项集中到单独一块;然后用固定种子跑基线,把运行时间、版本名、输出文件名对应记录,再按同一份配置重跑一次,从尺寸、构图、色调、细节四个维度比对。任何固定项改动都要升版本名,不要原地覆盖;比对不一致时先回退到只含固定项的最小工作流再排查。

列出当前工作流里全部可调参数并分成固定项与随机项

先做一次清点,把界面上能改的、节点里写死的、从外部文件加载的参数都列出来。分类标准是:改变它会改变画面语义或结构的,归固定项;只影响同一套设定下的细微差异或产出数量的,归随机项。字段位置一列写的是该参数在工作流导出文件中的实际落点,下面的路径是占位写法,需要按你导出的 JSON 替换节点名;节点 id 通常不稳定,建议用节点标题定位而不是数字 id。

参数名作用固定或随机对应字段位置
底模权重文件决定画风与语义理解固定<checkpoint_loader>.inputs.ckpt_name
VAE影响解码色彩与细节固定<vae_loader>.inputs.vae_name
采样器 sampler决定去噪轨迹固定<sampler>.inputs.sampler_name
调度器 scheduler决定噪声调度方式固定<sampler>.inputs.scheduler
步数 steps迭代次数固定(同版本内)<sampler>.inputs.steps
CFG提示词约束强度固定<sampler>.inputs.cfg
宽高 width / height构图与取景范围固定<empty_latent>.inputs.width / height
种子 seed起始噪声基线时固定<sampler>.inputs.seed
LoRA 名称与权重风格或角色增强固定<lora_loader>.inputs.lora_name / strength
ControlNet 权重结构约束强度固定<controlnet_apply>.inputs.strength
正负向提示词主体语义指令固定(模板部分)<text_encode>.inputs.text
批次数 batch_size单次产出数量随机/可变<sampler>.inputs.batch_size
种子递增策略批内变化方式随机<seed_control>.inputs.policy
放大倍数输出分辨率固定<upscale>.inputs.scale

清点完可以先只保留一张表,不要急着改工作流。表格的作用是让“这版到底改了什么”有据可查;如果某一项你自己也说不清固定与否,默认先归固定项,等确认不影响结果再放进随机区。

把固定项写进工作流配置并给这份配置起版本名

固定项单独成文件,随机项单独成块,这是后续能被找回和复用的前提。下面是一个通用骨架,字段名可以按你的实际工作流替换,占位符保留了尖括号:

先把工作流参数锁进配置再谈复现——ArtCraft 可控出图的搭法
# workflows/artcraft/<version>/config.yaml
meta:
  version: artcraft-portrait-v1      # 版本名,唯一且不再改动
  created_at: <YYYY-MM-DD>
  owner: <负责人的名字>
  note: <一句话说明这版相对上一版改了什么>

fixed:
  checkpoint: <ckpt_name>
  vae: <vae_name>
  sampler: <sampler_name>
  scheduler: <scheduler_name>
  steps: <int>
  cfg: <float>
  width: <int>
  height: <int>
  seed: <int>                      # 基线使用的固定种子
  lora:
    - name: <lora_name>
      strength: <float>
  controlnet:
    strength: <float>
  prompt_template: |
    <正向提示词主体>

random:
  seed_policy: <fixed|increment|random>
  batch_size: <int>
  slots:
    - hair_color
    - background

文件命名建议固定成 <流程>-<用途>-v<序号>,目录按流程和版本两级分开:配置放 workflows/artcraft/artcraft-portrait-v1/config.yaml,运行记录放 runs/artcraft/artcraft-portrait-v1/<run_id>/。规则只有一条:任何固定项改动都要新建 v2、v3,不要在原目录上直接覆盖。覆盖一次,之前所有基于 v1 的输出就失去了对照物。

用固定种子跑一次并留下输出记录

基线运行的目的不是出一张好看的图,而是建立一个可回查的参照点。跑之前确认随机项里的种子策略是 fixed,并且界面上的种子输入没有被手动改写;某些工具会在种子框留“随机”钩子,这个钩子必须先去掉。跑完后立刻落一份 manifest,把运行时间、参数版本名、输出文件名三者绑在一起:

先把工作流参数锁进配置再谈复现——ArtCraft 可控出图的搭法
{
  "run_id": "<YYYYMMDD-HHMM-序号>",
  "version": "artcraft-portrait-v1",
  "config_path": "workflows/artcraft/artcraft-portrait-v1/config.yaml",
  "started_at": "<开始时间>",
  "finished_at": "<结束时间>",
  "seed": <实际使用的种子>,
  "outputs": [
    "outputs/00001-artcraft-portrait-v1-seed<N>.png"
  ]
}

输出文件名里带上版本名和种子,是为了能从一张图反查到配置,而不是靠记忆。如果工具支持把 manifest 直接写到输出目录同层,优先用工具产出,再手工补齐版本名和配置路径,避免两处记录对不上。

按存档配置重跑第二次,比对两次输出

第二次运行只有输入不同:清空工作流、重新加载 config.yaml,其他一概不动,包括输出目录规则。比对时按四个维度逐项看,不要只扫一眼整体感觉:

  1. 尺寸:像素宽高是否完全一致,文件元信息里的分辨率是否相同。
  2. 构图:主体位置、取景范围、元素数量与排布是否一致。
  3. 色调:整体亮度、对比、偏色倾向是否一致,可以把两张图并排或做缩略图对比。
  4. 细节:纹理、边缘、局部小结构是否落在同一位置。

发现不一致时,排查方向按代价从低到高排:先看 manifest 里记录的种子和实际传入的种子是否相同;再核对采样器、调度器名称有没有拼写或大小写差异,这类名称在不同版本里可能被重命名;接着确认底模、VAE、LoRA 文件是否被替换过,有条件就对比文件哈希;最后才怀疑节点或插件版本差异、缓存未清理导致复用旧中间结果。不确定的情况下,先退回到只含固定项的最小工作流跑一遍,再逐步把节点加回来,能较快定位是哪一段引入的差异。

先把工作流参数锁进配置再谈复现——ArtCraft 可控出图的搭法

把随机项集中到单独一处,说明允许变化的边界

随机项混进固定参数里,是复现失败最常见的原因之一。所有会变的东西只放在配置的 random 块里,固定块里不允许出现会被运行时覆盖的值。常见的随机项清单与边界可以这样定:

  • 种子策略:批内递增或完全随机。允许的变化范围是同一套固定项下的不同噪声起点;一旦跨版本,种子不具备可比性。
  • 批次数 batch_size:只影响一次产出多少张,不影响单张结果。
  • 提示词词槽:发色、背景、配饰等可替换片段。允许在预设词表内替换,超出词表即视为新配置。
  • 放大倍数:如果不作为固定项,需要限定在单一取值,不要在同版本内浮动。

越界的处理动作要写死:任何随机项的取值超出上述范围,就把它从 random 移到 fixed,升一个新版本名,重跑基线并重新记录 manifest,同时在 note 里写明移位原因。这样做的代价是版本号增长得快,好处是任何时候翻出一张图,都能顺着文件名找到那份没被改过的配置。