@mcptoolshop/style-dataset-lab 3.3.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/README.es.md +117 -55
- package/README.fr.md +125 -65
- package/README.hi.md +117 -68
- package/README.it.md +119 -58
- package/README.ja.md +124 -74
- package/README.md +73 -7
- package/README.pt-BR.md +128 -63
- package/README.zh.md +116 -65
- package/bin/sdlab.js +100 -4
- package/lib/adapters/ai-toolkit.js +224 -35
- package/lib/adapters/comfyui-runner.js +79 -26
- package/lib/adapters/comfyui-workflows.js +94 -11
- package/lib/adapters/diffusers-lora.js +37 -5
- package/lib/adapters/generic-image-caption.js +43 -5
- package/lib/args.js +16 -1
- package/lib/asset-ingest.js +575 -0
- package/lib/asset-masks.js +323 -0
- package/lib/asset-source.js +1176 -0
- package/lib/batch-modes.js +29 -8
- package/lib/batch-runs.js +29 -1
- package/lib/batch-sheet-render.js +13 -3
- package/lib/brief-compiler.js +19 -0
- package/lib/candidate-sheet.js +327 -0
- package/lib/canon-author.js +350 -0
- package/lib/canon-build/build.js +146 -93
- package/lib/canon-review-gate.js +205 -0
- package/lib/captions.js +57 -0
- package/lib/card.js +74 -2
- package/lib/colab-launcher-guards.js +285 -0
- package/lib/comfyui.js +116 -18
- package/lib/config.js +116 -12
- package/lib/critique-engine.js +36 -2
- package/lib/eligibility.js +121 -9
- package/lib/eval-pack.js +14 -14
- package/lib/eval-runs.js +33 -0
- package/lib/export.js +122 -34
- package/lib/freeze-gate.js +16 -3
- package/lib/freeze-stamp.js +28 -3
- package/lib/generated-provenance.js +194 -6
- package/lib/implementation-packs.js +95 -17
- package/lib/ingest.js +396 -0
- package/lib/judgment-provenance.js +220 -0
- package/lib/lane1-render.js +668 -0
- package/lib/measure.js +422 -0
- package/lib/memory-store.js +663 -0
- package/lib/model-licences.js +305 -0
- package/lib/npy-meta.js +130 -0
- package/lib/paths.js +196 -7
- package/lib/png-meta.js +512 -0
- package/lib/records.js +54 -8
- package/lib/reingest-selected.js +113 -17
- package/lib/reingest.js +27 -3
- package/lib/run-manifest.js +159 -25
- package/lib/run-summary.js +12 -6
- package/lib/runtime-runs.js +45 -4
- package/lib/snapshot.js +114 -15
- package/lib/split.js +364 -48
- package/lib/train-runs.js +214 -0
- package/lib/training-manifests.js +114 -21
- package/lib/training-packages.js +147 -15
- package/lib/verifier.js +3 -0
- package/lib/verify-chain.js +367 -0
- package/lib/workflow-profiles.js +24 -3
- package/package.json +4 -3
- package/runtime/comfyui/txt2img-qwen.json +38 -0
- package/runtime/comfyui/txt2img-standard.json +21 -0
- package/scripts/_resume.js +62 -0
- package/scripts/_shared-args.js +44 -0
- package/scripts/asset-ingest.js +160 -0
- package/scripts/brief-compile.js +2 -1
- package/scripts/brief-show.js +2 -1
- package/scripts/canon-bind.js +2 -2
- package/scripts/canon-build.js +27 -20
- package/scripts/canon-draft.js +82 -0
- package/scripts/canon-drift.js +16 -7
- package/scripts/canon-freeze-status.js +14 -6
- package/scripts/canon-freeze.js +31 -11
- package/scripts/canon-unfreeze.js +17 -9
- package/scripts/card.js +2 -2
- package/scripts/colab/REAL_SERVICE_ASSUMPTIONS.md +14 -0
- package/scripts/colab/ai-toolkit-override-py315.txt +45 -0
- package/scripts/colab/colab_window.sh +587 -0
- package/scripts/colab/lane1_render.py +970 -0
- package/scripts/colab/launch_guards.py +564 -0
- package/scripts/colab/launch_lane1_stub.sh +309 -0
- package/scripts/colab/launch_lane3_stub.sh +366 -0
- package/scripts/colab/remote_runner.py +59 -0
- package/scripts/compare.js +2 -2
- package/scripts/critique.js +16 -1
- package/scripts/curate.js +2 -2
- package/scripts/doctor.js +182 -55
- package/scripts/eligibility.js +42 -2
- package/scripts/eval-pack.js +2 -2
- package/scripts/eval-run.js +2 -2
- package/scripts/export.js +2 -2
- package/scripts/generate-controlnet.js +45 -25
- package/scripts/generate-identity.js +53 -23
- package/scripts/generate-ipadapter.js +44 -23
- package/scripts/generate.js +86 -17
- package/scripts/implementation-pack.js +2 -2
- package/scripts/ingest.js +145 -0
- package/scripts/init.js +73 -13
- package/scripts/measure.js +170 -0
- package/scripts/measure_image.py +458 -0
- package/scripts/migrate-records.js +142 -0
- package/scripts/painterly-test.js +4 -3
- package/scripts/painterly.js +7 -3
- package/scripts/qwen_generate.py +138 -20
- package/scripts/reingest.js +2 -2
- package/scripts/sheet.js +142 -0
- package/scripts/snapshot.js +2 -2
- package/scripts/split.js +2 -2
- package/scripts/training-manifest.js +2 -2
- package/scripts/training-package.js +2 -2
- package/scripts/training-profile.js +2 -2
- package/scripts/verify.js +67 -0
- package/scripts/workflow-list.js +2 -1
- package/scripts/workflow-show.js +2 -1
package/README.zh.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="README.
|
|
2
|
+
<a href="README.md">English</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português (BR)</a>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License"></a>
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
编写你的视觉规则。生成艺术作品。根据这些规则评估每张图像。将结果作为版本化的、可审计的训练数据进行输出——然后将训练好的模型应用于实际的生产工作流程中,并将最佳输出反馈到你的语料库中。
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
“风格数据集实验室”将你记录的关于你的艺术风格的内容与你实际用于训练的数据集联系起来,然后将整个流程贯穿到生产阶段。你定义一套规范——轮廓规则、调色板约束、材质语言,以及对你的项目有意义的任何内容。流水线生成候选作品,根据这些规则对其进行评分,并将批准的作品打包成可重现的数据集,其中每条记录都解释了它被包含的原因。
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
然后,生产工作台接管:从项目的事实中编译生成简报,通过 ComfyUI 运行,评估输出结果,批量生成表现图和环境图,选择最佳结果,并将它们重新导入作为新的候选作品。循环结束:生成、选择、审查、改进。
|
|
21
21
|
|
|
22
22
|
## 流水线
|
|
23
23
|
|
|
@@ -27,8 +27,15 @@ sdlab init my-project --domain character-design
|
|
|
27
27
|
|
|
28
28
|
# Generate candidates via ComfyUI, then review them
|
|
29
29
|
sdlab generate inputs/prompts/wave1.json --project my-project
|
|
30
|
+
sdlab sheet outputs/candidates --project my-project # HTML contact sheet to triage
|
|
30
31
|
sdlab curate <id> approved "Strong silhouette, correct faction palette"
|
|
31
32
|
|
|
33
|
+
# Already have images? Bring them in without generating anything
|
|
34
|
+
sdlab ingest ~/renders/wave1 --project my-project
|
|
35
|
+
|
|
36
|
+
# Measure what the pixels actually are — palette and texture, as numbers
|
|
37
|
+
sdlab measure outputs/candidates --project my-project
|
|
38
|
+
|
|
32
39
|
# Bind approved work to constitution rules
|
|
33
40
|
# (`sdlab bind` is a shorter alias for `canon-bind`)
|
|
34
41
|
sdlab canon-bind --project my-project
|
|
@@ -56,11 +63,47 @@ sdlab select --run run_2026-04-16_001 --approve 001.png,003.png
|
|
|
56
63
|
sdlab reingest selected --selection selection_2026-04-16_001
|
|
57
64
|
```
|
|
58
65
|
|
|
59
|
-
|
|
66
|
+
最后一条命令就是关键。选定的输出会通过与所有其他内容相同的审查流程。语料库不断增长,规则始终有效。
|
|
67
|
+
|
|
68
|
+
## 资产通道——3D 导出作为训练数据
|
|
69
|
+
|
|
70
|
+
`sdlab ingest` 信任原始图像。`sdlab asset ingest` 签订一份**协议**。
|
|
71
|
+
|
|
72
|
+
当一个 3D 资产通过其验收关口后,从 N 个角度重新渲染它,可以得到一个视角一致的图像——这是通过构建方式实现的,而基于视角的扩散模型无法保证这一点。资产通道将这些导出作为带有来源信息的训练数据:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Validate an export's manifest end to end, run the gates, write nothing
|
|
76
|
+
sdlab asset ingest ~/exports/dragon_dense --project my-project --dry-run
|
|
77
|
+
|
|
78
|
+
# Register it: records, candidates, masks, channels, receipt
|
|
79
|
+
sdlab asset ingest ~/exports/dragon_dense --project my-project
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
导出目录包含一个 `asset-source.json` 清单(模式 **1.3.0**),声明了其通道、调色板频段、关口阈值、验收结果、风格注册表,以及渲染图像的生成方式和来源。sdlab 会根据实际字节验证每个声明,并且如果发现任何违规行为,将拒绝整个导入——任何不符合规范的清单都不会被注册。
|
|
83
|
+
|
|
84
|
+
**连接点:** sdlab 提供机制,资产提供语义。sdlab 从不进行光线追踪,从不进行渲染,并且从不认为名为“来源”的通道是特殊的。它会证明、测量、注册和打包。数字的*含义*与资产相关联。
|
|
85
|
+
|
|
86
|
+
协议强制执行的内容:
|
|
87
|
+
|
|
88
|
+
| 阶段 | 验证的内容 |
|
|
89
|
+
|---|---|
|
|
90
|
+
| **schema** | 形状、ID、格式良好的调色板频段,以及实际上为 `"accepted"` 的验收结果 |
|
|
91
|
+
| **containment** | 每个引用的路径都*位于*导出目录中(它是不受信任的输入),并且存在 |
|
|
92
|
+
| **encoding** | PNG 的 IHDR 与其声明的编码匹配;NPY 标头的 dtype 和形状与其声明的 dtype 和形状匹配。如果清单“看起来正确”,但与它的字节不一致,那么这就是本通道旨在阻止的情况。 |
|
|
93
|
+
| **categorical** | 索引 PNG 证明 PLTE ⊆ 声明的调色板;使用 `nearest` 过滤的通道会进行*详尽的*像素解码;分类 NPY 会进行详尽的值扫描。 |
|
|
94
|
+
| **gates** | 调色板关口在每次渲染时运行,基于清单自身的频段和阈值——如果渲染失败,则会发出明确的拒绝并报告,而不会悄悄地接受。 |
|
|
95
|
+
|
|
96
|
+
记录以**未整理**(`judgment: null`)的形式与 `provenance.source: "asset"` 一起导入,并携带
|
|
97
|
+
验收块的完整内容、每个文件的哈希值、相机和导向信息、关口测量值、声明的风格注册表以及每个图像的生成帧和种子。然后,它们会经历与其他记录相同的整理过程。
|
|
98
|
+
|
|
99
|
+
导入还会报告清单*未*声明的内容——未知的风格注册表、缺失的 `identity.subject_name`、缺失的生成来源——作为**通知**,而不是
|
|
100
|
+
失败。它们会显示在收据中并在 CLI 中打印。如果有一个问题没有人被告知,那么就无法解决这个问题;并且,由于清单可以*声明*其渲染是确定性的派生,并且没有自己的种子,因此该通道不会报告任何导出的差距。
|
|
101
|
+
|
|
102
|
+
完整的协议、验证层级以及每个字段背后的原因:[docs/asset-lane-design.md](docs/asset-lane-design.md)。
|
|
60
103
|
|
|
61
104
|
## 规范创作
|
|
62
105
|
|
|
63
|
-
|
|
106
|
+
在数据集流水线运行之前,`sdlab canon *` 命名空间将你的项目的规范实体存储转换为训练和生产实际使用的三个投影——并锁定那些不应漂移的条目。
|
|
64
107
|
|
|
65
108
|
```bash
|
|
66
109
|
# Build three projections from the canon entity store:
|
|
@@ -76,62 +119,64 @@ sdlab canon freeze kael_maren --project my-project --reason "prologue portrait l
|
|
|
76
119
|
sdlab canon drift --project my-project
|
|
77
120
|
```
|
|
78
121
|
|
|
79
|
-
|
|
122
|
+
本地模型也可以草拟规范,但它不能决定规范。`sdlab canon draft <class_id> --endpoint <url> --brief "<text>" --out <path>` 向仅循环的、与 OpenAI 兼容的服务器请求规范条目和提示,并使用 `status: "draft"`、`judgment: null` 和草拟模型对每个输出进行标记。在有人批准之前,草拟内容不能被冻结:冻结关口拒绝任何由模型草拟的条目,除非有人的批准、理由以及批准的确切草拟的哈希值。
|
|
80
123
|
|
|
81
|
-
|
|
124
|
+
`canon build` 是基于内容的——它的输出由 `canon_sha` 键控并缓存,因此未更改的规范可以立即重建。`canon freeze` 见证每次冻结,并附加到 `freeze-events.jsonl` 审计跟踪中:`frozen` 条目完全拒绝重新生成,`soft-advisory` 条目默认拒绝(使用 `--i-know` 绕过)。`canon drift` 重新计算每个已监视条目的哈希值,并标记自上次干净构建以来发生更改的任何内容。
|
|
82
125
|
|
|
83
|
-
|
|
126
|
+
完整的流程在手册中:[规范构建](handbook/canon-build/)、[规范冻结](handbook/canon-freeze/) 和 [双 LoRA 堆叠](handbook/two-lora-stacking/)。
|
|
127
|
+
|
|
128
|
+
## 它产生的内容
|
|
84
129
|
|
|
85
130
|
七个数据集工件和一个完整的生产工作台。每个工件都链接到其前身,因此你可以追溯任何训练记录到批准它的规则。
|
|
86
131
|
|
|
87
132
|
| 工件 | 它是什么 |
|
|
88
133
|
|----------|-----------|
|
|
89
|
-
| **Snapshot** |
|
|
134
|
+
| **Snapshot** | 带有配置指纹的冻结记录选择。每个包含都有明确的理由。 |
|
|
90
135
|
| **Split** | 训练/验证/测试分区,其中主题系列不会跨越边界。 |
|
|
91
136
|
| **Export package** | 自包含数据集:清单、元数据、图像、分割、数据集卡、校验和。 |
|
|
92
|
-
| **Eval pack** |
|
|
93
|
-
| **Training package** |
|
|
94
|
-
| **Eval scorecard** |
|
|
95
|
-
| **Implementation pack** |
|
|
137
|
+
| **Eval pack** | 了解规范的测试任务:车道覆盖、禁止漂移、锚点/黄金样本、主题连续性。 |
|
|
138
|
+
| **Training package** | 通过适配器(`diffusers-lora`、`generic-image-caption`)构建可用于训练的布局。相同的真实数据,不同的格式。 |
|
|
139
|
+
| **Eval scorecard** | 根据评估包对生成的输出进行评分,从而得出每个任务的通过/失败结果。 |
|
|
140
|
+
| **Implementation pack** | 提示示例、已知失败案例、连续性测试和重新导入指南。 |
|
|
96
141
|
|
|
97
|
-
|
|
142
|
+
生产工作台新增:
|
|
98
143
|
|
|
99
|
-
| 表面 |
|
|
144
|
+
| 表面 | 其作用 |
|
|
100
145
|
|---------|-------------|
|
|
101
|
-
| **Compiled brief** |
|
|
102
|
-
| **Run** |
|
|
146
|
+
| **Compiled brief** | 从工作流程配置文件 + 项目真实数据中生成确定性的生成指令。 |
|
|
147
|
+
| **Run** | 冻结的执行工件:简要说明 + 种子 + ComfyUI 输出 + 清单。 |
|
|
103
148
|
| **Critique** | 对运行输出相对于规范进行结构化的多维评估。 |
|
|
104
|
-
| **Batch** |
|
|
105
|
-
| **Selection** |
|
|
106
|
-
| **Re-ingest** |
|
|
149
|
+
| **Batch** | 协调多插槽生产(表情表、环境板、轮廓包)。 |
|
|
150
|
+
| **Selection** | 创意决策工件:选择了哪些输出,原因是什么,以及它们的来源。 |
|
|
151
|
+
| **Re-ingest** | 选定的输出作为包含完整生成来源的候选记录返回。 |
|
|
107
152
|
|
|
108
|
-
##
|
|
153
|
+
## 为什么存在这个系统
|
|
109
154
|
|
|
110
|
-
|
|
155
|
+
在任何视觉 AI 流水线中,训练数据是最有价值的资源。但大多数训练数据只是一个包含图像的文件夹,没有历史记录、没有判断依据,也没有与它应该遵循的风格规则的联系。
|
|
111
156
|
|
|
112
|
-
|
|
157
|
+
“风格数据集实验室”使这种联系变得明确。您的规范定义了规则。您的评分标准定义了评分维度。您的整理记录了判断过程。您的规范绑定证明了这种联系。并且您的数据集将所有这些内容作为结构化、可查询、可重现的真实数据进行保留。
|
|
113
158
|
|
|
114
|
-
|
|
159
|
+
实际结果:当您的 LoRA 发生漂移时,您可以询问*原因*。当您的下一个训练需要更好的数据时,您会确切地知道哪些记录接近失败,以及它们未能满足的单一规则。当新的团队成员询问项目的视觉语言时,答案不是一个 Figma 板——而是一个可搜索的规范,其中包含 1182 个分级示例。
|
|
115
160
|
|
|
116
|
-
##
|
|
161
|
+
## 已在生产中验证
|
|
117
162
|
|
|
118
|
-
这不是一个演示流水线。两个真实的风格 LoRA
|
|
163
|
+
这不是一个演示流水线。两个真实的风格 LoRA 已经通过它完成了端到端的流程——相同的规范 → 整理 → 训练 → 发布循环,位于整理频谱的相对两端。
|
|
119
164
|
|
|
120
|
-
- **[Tallow Fen](handbook/case-study-tallow-fen/)
|
|
121
|
-
- **[Rustline](handbook/case-study-rustline/)**(概念设计)——密集、预先构建的规范,在 180
|
|
165
|
+
- **[Tallow Fen](handbook/case-study-tallow-fen/)**(生物设计)——一个从零开始构建的生物图鉴规范,在 293 个整理的记录中,约有 **34% 的批准率**(169 个被拒绝——筛选非常严格)。发布 `tallow_fen_style_v3.safetensors`,参数为 1.5,在 `qwen-image` 上运行。
|
|
166
|
+
- **[Rustline](handbook/case-study-rustline/)**(概念设计)——密集、预先构建的规范,在 180 个记录中,约有 **96% 的批准率**。发布 `rustline_v3ckpt_1500.safetensors`,参数为 1.0,在 `qwen-image` 上运行,并在后续项目中被第二个项目重用。
|
|
122
167
|
|
|
123
|
-
|
|
168
|
+
相同的流水线,两种生产配置文件:整理筛选是真实的(它会严格拒绝开放主题),并且严格的规范会产生很高的接受率。
|
|
124
169
|
|
|
125
170
|
## 五个领域,真实的规则
|
|
126
171
|
|
|
127
|
-
|
|
172
|
+
不是占位符模板。每个领域都提供生产级别的规范规则、车道定义、评分标准和组词汇。
|
|
128
173
|
|
|
129
|
-
| 领域 |
|
|
174
|
+
| 领域 | 车道 | 需要判断的内容 |
|
|
130
175
|
|--------|-------|-----------------|
|
|
131
|
-
| **game-art** |
|
|
132
|
-
| **character-design** |
|
|
133
|
-
| **creature-design** |
|
|
134
|
-
| **architecture** | 外部、内部、街景、结构细节、废墟、景观 |
|
|
176
|
+
| **game-art** | 角色、环境、道具、UI、飞船、内部、设备 | 在游戏规模下,轮廓、派系特征、磨损和老化 |
|
|
177
|
+
| **character-design** | 肖像、全身、旋转图、表情表、动作姿势 | 比例、服装逻辑、个性、姿势清晰度 |
|
|
178
|
+
| **creature-design** | 概念、正投影、细节研究、动作、比例参考、栖息地 | 解剖结构、进化逻辑、轮廓区分 |
|
|
179
|
+
| **architecture** | 外部、内部、街景、结构细节、废墟、景观 | 结构、材料一致性、透视、时代一致性 |
|
|
135
180
|
| **vehicle-mech** | 外部、驾驶舱、组件、示意图、轮廓图、损坏变体 | 机械逻辑、设计语言、访问点、损坏叙事 |
|
|
136
181
|
|
|
137
182
|
## 项目结构
|
|
@@ -160,19 +205,23 @@ projects/my-project/
|
|
|
160
205
|
|
|
161
206
|
## 信任属性
|
|
162
207
|
|
|
163
|
-
|
|
208
|
+
这些不是理想化的。它们是强制执行的。
|
|
164
209
|
|
|
165
|
-
- **快照是不可变的。** 配置指纹(SHA-256
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
- **没有模型会验证自己的输出。**
|
|
170
|
-
-
|
|
171
|
-
-
|
|
210
|
+
- **快照是不可变的。** 配置指纹(SHA-256)证明没有发生任何更改。ID 以原子方式声明,因此两个并发运行不能交错到同一个目录中。
|
|
211
|
+
- **分割可以防止数据泄露——并且验证这一点的是一个独立的检查。** 主题族(按身份、谱系或规范化的 ID 词干)绝不会跨越分区边界,并且第二个检查会从头开始重新推导主题身份,而不是重新读取分割本身使用的映射。数据集卡仅在两个检查都运行并通过时声明“数据泄露:无(已验证)”;如果分割早于第二个检查,则会明确说明这一点。
|
|
212
|
+
- **清单是固定的协议。** 导出哈希 + 配置指纹,并且 `validate` 会重新哈希 `checksums.txt` 列出的每个文件——因此,替换已完成导出中的图像会被捕获,包括在创建清单之前进行的检查。
|
|
213
|
+
- **每次运行都会固定其确切的图。** 每次生成都会记录 `comfy_workflow_sha` + 模型/LoRA 内容哈希 + 种子策略,因此可以完全重现一次生成。JS 和 Python 运行器通过一个测试来确保字节级的哈希值完全相同,该测试会同时启动两者。模型哈希是可选的(`--hash-models`),并且绝不会伪造——无法解析的文件会记录 `sha256: null` 并附带说明。
|
|
214
|
+
- **没有模型会验证自己的输出。** 判决会记录 `judged_by_model` 和 `generator_model`;如果它们曾经是同一个模型,则会发出警告。
|
|
215
|
+
- **判决会说明是谁做出的。** `eligibility audit` 区分了某人编写的判决和批量脚本生成的判决,因此,描述的是一个类别而不是一个图像的理由,不能被视为策展。
|
|
216
|
+
- **测量不是判决。** `sdlab measure` 将数字附加到记录中。它绝不会设置判决、拟合或批准——并且对于图像而言,如果某个指标未定义,它会记录 `null` 而不是一个合理的数字。
|
|
217
|
+
- **发布可以证明每张图像的来源。** `sdlab verify --project <name>` 会为每条记录遍历链条:记录上的所有者和许可,它所绑定的规范条目(通过哈希),每个模型和 LoRA 的许可(SPDX ID、许可 URL、读取日期和文件哈希),以及运行清单中的工作流哈希。如果缺少链接,则检查会失败,而不是通过。
|
|
218
|
+
- **适配器不能改变真相。** 不同的布局,相同的记录。没有添加、没有删除、没有重新分类。
|
|
219
|
+
- **生成的输出会通过审核重新进入。** 没有绕过。像其他内容一样进行策展和绑定。外部生成的图像通过 `sdlab ingest` 以相同的方式进入,未经策展。
|
|
220
|
+
- **失败是可见的。** 缺少记录、无法放置的图像或无法构建的标题会停止导出或训练包,而不是悄悄地缩小它。
|
|
172
221
|
|
|
173
222
|
## 星际货运
|
|
174
223
|
|
|
175
|
-
|
|
224
|
+
该存储库包含一个完整的可用示例:1182 条记录、5 个派系、7 条路线、24 条宪法规则、892 个已批准的资产、2 个训练配置文件。一个粗犷的科幻 RPG 视觉规范,已完全策展。
|
|
176
225
|
|
|
177
226
|
```bash
|
|
178
227
|
git clone https://github.com/mcp-tool-shop-org/style-dataset-lab
|
|
@@ -184,7 +233,7 @@ sdlab split build --project star-freight # zero subject leakage
|
|
|
184
233
|
|
|
185
234
|
## 下游格式
|
|
186
235
|
|
|
187
|
-
`sdlab` 拥有数据集。格式转换由 [`repo-dataset`](https://github.com/mcp-tool-shop-org/repo-dataset) 处理:TRL、LLaVA、Qwen2-VL、JSONL、Parquet 等。`repo-dataset`
|
|
236
|
+
`sdlab` 拥有数据集。格式转换由 [`repo-dataset`](https://github.com/mcp-tool-shop-org/repo-dataset) 处理:TRL、LLaVA、Qwen2-VL、JSONL、Parquet 等。`repo-dataset` 进行渲染;它绝不会决定是否包含。
|
|
188
237
|
|
|
189
238
|
## 安装
|
|
190
239
|
|
|
@@ -192,11 +241,11 @@ sdlab split build --project star-freight # zero subject leakage
|
|
|
192
241
|
npm install -g @mcptoolshop/style-dataset-lab
|
|
193
242
|
```
|
|
194
243
|
|
|
195
|
-
需要 Node.js 20+
|
|
244
|
+
需要 Node.js 20+ 和本地主机 8188 上的 [ComfyUI](https://github.com/comfyanonymous/ComfyUI) 进行生成。
|
|
196
245
|
|
|
197
|
-
###
|
|
246
|
+
### 尝试不使用 ComfyUI
|
|
198
247
|
|
|
199
|
-
|
|
248
|
+
您可以使用捆绑的星际货运项目探索完整的非生成表面——检查、策展、快照、分割、导出——而无需安装 ComfyUI 或下载任何 SDXL 权重。
|
|
200
249
|
|
|
201
250
|
```bash
|
|
202
251
|
# Scaffold a fresh project (no ComfyUI needed)
|
|
@@ -209,9 +258,9 @@ sdlab project doctor --project test
|
|
|
209
258
|
sdlab snapshot create --dry-run --project star-freight
|
|
210
259
|
```
|
|
211
260
|
|
|
212
|
-
`sdlab project doctor`
|
|
261
|
+
`sdlab project doctor` 验证每个项目配置(宪法、路线、评分标准、术语),并在不触及 GPU 的情况下报告资格。任何更改生成状态的命令都接受 `--dry-run` 以首先预览效果。
|
|
213
262
|
|
|
214
|
-
如果您忘记了 `--project`,CLI
|
|
263
|
+
如果您忘记了 `--project`,CLI 将回退到 `projects/` 下找到的第一个项目,并打印警告——明确传递 `--project` 以使其停止。
|
|
215
264
|
|
|
216
265
|
### 恢复中断的运行
|
|
217
266
|
|
|
@@ -227,41 +276,43 @@ sdlab generate inputs/prompts/wave1.json --project my-project --resume
|
|
|
227
276
|
sdlab batch generate --resume batch_2026-04-22_001 --project my-project
|
|
228
277
|
```
|
|
229
278
|
|
|
230
|
-
|
|
279
|
+
这两个命令都有效,因为每个插槽都会在其完成时以原子方式写入其清单条目——运行过程中发生崩溃绝不会破坏部分状态。
|
|
231
280
|
|
|
232
281
|
## 故障排除
|
|
233
282
|
|
|
234
|
-
|
|
283
|
+
常见故障模式和解决方法:
|
|
235
284
|
|
|
236
|
-
|
|
237
|
-
ComfyUI
|
|
285
|
+
**`ECONNREFUSED 127.0.0.1:8188` 在任何 `sdlab generate` / `sdlab run generate` / `sdlab batch generate` 上**
|
|
286
|
+
ComfyUI 尚未运行。启动 ComfyUI(`python main.py --listen 127.0.0.1 --port 8188`),并使用 `curl http://127.0.0.1:8188/system_stats` 进行确认。要指向不同的主机/端口,请设置 `COMFY_URL=http://host:port`。
|
|
238
287
|
|
|
239
288
|
**`missing checkpoint` / `LoRA weight not found`**
|
|
240
|
-
|
|
289
|
+
您的工作流配置文件指定了一个不在 ComfyUI 的 `models/checkpoints/` 或 `models/loras/` 文件夹中的模型文件。打开 `projects/<project>/workflows/profiles/<profile>.json`,找到 `checkpoint` 或 `lora` 字段,然后下载引用的权重或将其替换为您已有的权重。重新运行 `sdlab project doctor --project <project>` 以确认修复。
|
|
241
290
|
|
|
242
291
|
**`sdlab project doctor` 错误**
|
|
243
|
-
Doctor
|
|
244
|
-
- `E_PROJECT_NOT_FOUND
|
|
292
|
+
Doctor 返回结构化的错误代码。常见错误:
|
|
293
|
+
- `E_PROJECT_NOT_FOUND`——项目目录不存在于 `projects/` 下。检查拼写。
|
|
245
294
|
- `E_CONFIG_INVALID`——五个 JSON 配置文件中的一个未能通过模式验证。`hint` 字段指定了错误的 文件和字段。
|
|
246
|
-
- `E_RECORD_DRIFT
|
|
295
|
+
- `E_RECORD_DRIFT`——记录的配置指纹不再与其来源匹配。如提示所述,重新策展或重新绑定。
|
|
247
296
|
|
|
248
297
|
**`No --project specified, falling back to <name>`**
|
|
249
|
-
一个软警告。明确传递 `--project <name>`
|
|
298
|
+
一个软警告。明确传递 `--project <name>` 以选择正确的项目并停止警告。
|
|
250
299
|
|
|
251
300
|
**绘画风格 / VRAM 内存不足问题**
|
|
252
|
-
请参阅 `docs/internal/HANDOFF.md
|
|
301
|
+
请参阅 `docs/internal/HANDOFF.md` 以获取绘画风格去噪调整说明。简而言之:降低去噪强度、减少批处理大小或在工作流配置文件中切换到较小的检查点。
|
|
253
302
|
|
|
254
303
|
**报告错误**
|
|
255
|
-
在 https://github.com/mcp-tool-shop-org/style-dataset-lab/issues 上提交问题,并提供您的 sdlab 版本(`sdlab --version`)、Node 版本(`node -v
|
|
304
|
+
在 https://github.com/mcp-tool-shop-org/style-dataset-lab/issues 上提交问题,并提供您的 sdlab 版本(`sdlab --version`)、Node 版本(`node -v`)、完整的命令以及结构化的错误输出。错误报告模板会预填充字段。
|
|
256
305
|
|
|
257
306
|
## 安全性
|
|
258
307
|
|
|
259
|
-
|
|
308
|
+
默认情况下为本地。没有遥测、没有分析,并且 `sdlab` CLI 不会进行任何外部请求:图像保留在您的 GPU 和文件系统中,并且 `canon draft` 拒绝任何非环回的端点。
|
|
309
|
+
|
|
310
|
+
唯一的例外是“选择加入”功能。`scripts/colab/` 包含用于在您自己的 Google Colab 帐户上运行渲染或 LoRA 训练步骤的启动工具包。它们只会上传您指定的文件,并在不超过从您的 Colab 帐户余额中读取的预算限制的情况下运行,并在退出时停止自身的会话。这些工具包是**实验性的**:它们尚未完成完整的端到端测试。
|
|
260
311
|
|
|
261
|
-
##
|
|
312
|
+
## 许可
|
|
262
313
|
|
|
263
314
|
MIT
|
|
264
315
|
|
|
265
316
|
---
|
|
266
317
|
|
|
267
|
-
由 <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a>
|
|
318
|
+
由 <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a> 构建
|
package/bin/sdlab.js
CHANGED
|
@@ -18,6 +18,21 @@ const COMMANDS = {
|
|
|
18
18
|
'generate:controlnet': '../scripts/generate-controlnet.js',
|
|
19
19
|
'generate:ipadapter': '../scripts/generate-ipadapter.js',
|
|
20
20
|
'curate': '../scripts/curate.js',
|
|
21
|
+
// Bring images that were generated OUTSIDE sdlab into the pipeline. The
|
|
22
|
+
// documented production loop (brief→run→critique→batch→select→reingest) has
|
|
23
|
+
// never run on any project in this repo — real generation happens in
|
|
24
|
+
// external Python against Comfy Cloud, and until now those images had no
|
|
25
|
+
// CLI path in. `reingest generated` needs a trained LoRA's manifest;
|
|
26
|
+
// `reingest selected` needs a selection only the loop can mint.
|
|
27
|
+
'ingest': '../scripts/ingest.js',
|
|
28
|
+
// Contact sheet over ANY directory of candidates. The renderer already
|
|
29
|
+
// existed (lib/batch-sheet-render.js) but was reachable only via
|
|
30
|
+
// `batch sheet`, which needs a batch manifest nothing has ever produced —
|
|
31
|
+
// so five hand-rolled PIL contact-sheet scripts grew up in projects/ instead.
|
|
32
|
+
'sheet': '../scripts/sheet.js',
|
|
33
|
+
// Deterministic pixel measurement. Nothing in this tool opened an image
|
|
34
|
+
// before this: critique scores brief TEXT, not pixels.
|
|
35
|
+
'measure': '../scripts/measure.js',
|
|
21
36
|
'compare': '../scripts/compare.js',
|
|
22
37
|
'bind': '../scripts/canon-bind.js',
|
|
23
38
|
'canon-bind': '../scripts/canon-bind.js',
|
|
@@ -36,6 +51,7 @@ const COMMANDS = {
|
|
|
36
51
|
'eval-run': '../scripts/eval-run.js',
|
|
37
52
|
'implementation-pack': '../scripts/implementation-pack.js',
|
|
38
53
|
'reingest': '../scripts/reingest.js',
|
|
54
|
+
'verify': '../scripts/verify.js',
|
|
39
55
|
};
|
|
40
56
|
|
|
41
57
|
// Two-word commands under "project" namespace
|
|
@@ -87,6 +103,14 @@ const CANON_COMMANDS = {
|
|
|
87
103
|
'unfreeze': '../scripts/canon-unfreeze.js',
|
|
88
104
|
'freeze-status': '../scripts/canon-freeze-status.js',
|
|
89
105
|
'drift': '../scripts/canon-drift.js',
|
|
106
|
+
'draft': '../scripts/canon-draft.js',
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// Two-word commands under "asset" namespace — the asset lane
|
|
110
|
+
// (docs/asset-lane-design.md): manifest-driven, gated ingest of
|
|
111
|
+
// provenance-carrying asset exports, beside the bare `sdlab ingest`.
|
|
112
|
+
const ASSET_COMMANDS = {
|
|
113
|
+
'ingest': '../scripts/asset-ingest.js',
|
|
90
114
|
};
|
|
91
115
|
|
|
92
116
|
// ─── Per-command help ─────────────────────────────────────────────────
|
|
@@ -337,6 +361,41 @@ Subcommands:
|
|
|
337
361
|
|
|
338
362
|
Flags:
|
|
339
363
|
--project <name> Project to operate on`,
|
|
364
|
+
|
|
365
|
+
'verify': `sdlab verify --project <name> [--record <id>] [--snapshot <id>] [--json]
|
|
366
|
+
|
|
367
|
+
Verify the full offline provenance chain for CC-BY-4.0 release:
|
|
368
|
+
record (G5 owner + CC-BY-4.0) -> canon (G6 canon_sha + entry_sha256)
|
|
369
|
+
-> model licence (G4 SPDX id + licence_url + date_read) -> run manifest (workflow sha).
|
|
370
|
+
|
|
371
|
+
Flags:
|
|
372
|
+
--project <name> Project to verify
|
|
373
|
+
--record <id> Verify a single record id
|
|
374
|
+
--snapshot <id> Verify all records in a snapshot
|
|
375
|
+
--json Emit machine-readable JSON report`,
|
|
376
|
+
|
|
377
|
+
'asset ingest': `sdlab asset ingest <dir> --project <name> [--dry-run] [--json]
|
|
378
|
+
|
|
379
|
+
Register a provenance-carrying asset export into a project. The export
|
|
380
|
+
directory must contain an asset-source.json manifest; ingest validates it
|
|
381
|
+
end to end (schema, path containment, encoding proofs against actual file
|
|
382
|
+
bytes, categorical palette proofs, the acceptance verdict) and refuses
|
|
383
|
+
loudly on any violation — nothing registers on a bad manifest.
|
|
384
|
+
|
|
385
|
+
Admitted renders land as uncurated candidate records (judgment: null,
|
|
386
|
+
provenance.source: "asset") with per-render gate measurements attached.
|
|
387
|
+
An ingest-receipt.json under assets/<asset-id>/ lists every written path.
|
|
388
|
+
|
|
389
|
+
Positional:
|
|
390
|
+
dir Asset export directory (may live outside the
|
|
391
|
+
workspace — read-only source)
|
|
392
|
+
|
|
393
|
+
Flags:
|
|
394
|
+
--project <name> Project to register into
|
|
395
|
+
--dry-run Validate + run gates + report; write nothing
|
|
396
|
+
--json Emit the result as JSON on stdout
|
|
397
|
+
|
|
398
|
+
Contract reference: docs/asset-lane-design.md`,
|
|
340
399
|
};
|
|
341
400
|
|
|
342
401
|
// "bind" is a short alias for "canon-bind" — share help.
|
|
@@ -356,19 +415,26 @@ function printHelp() {
|
|
|
356
415
|
console.log(' init <name> Scaffold a new project from a domain template');
|
|
357
416
|
console.log(' project doctor Validate project config and structure');
|
|
358
417
|
console.log(' project migrate Migrate record schemas');
|
|
418
|
+
console.log(' verify Verify full provenance chain (record -> canon -> licence -> run)');
|
|
359
419
|
console.log('');
|
|
360
420
|
console.log('Pipeline:');
|
|
361
421
|
console.log(' generate Generate candidates from a prompt pack');
|
|
362
422
|
console.log(' generate:identity Generate named-subject identity images');
|
|
363
423
|
console.log(' generate:controlnet ControlNet-guided structural generation');
|
|
364
424
|
console.log(' generate:ipadapter IP-Adapter reference-guided generation');
|
|
425
|
+
console.log(' ingest <dir> Ingest externally-generated images as candidates');
|
|
365
426
|
console.log(' curate Move candidate to approved/rejected/borderline');
|
|
427
|
+
console.log(' sheet [<dir>] Render an HTML contact sheet for visual review');
|
|
428
|
+
console.log(' measure <target> Measure candidate pixels (palette, texture)');
|
|
366
429
|
console.log(' compare Record pairwise A-vs-B comparison');
|
|
367
430
|
console.log(' canon-bind Bind approved records to constitution rules');
|
|
368
431
|
console.log(' ("bind" is a short alias for canon-bind)');
|
|
369
432
|
console.log(' painterly Post-processing painterly style pass');
|
|
370
433
|
console.log(' painterly:test Calibrate painterly denoise level on sample images');
|
|
371
434
|
console.log('');
|
|
435
|
+
console.log('Asset lane:');
|
|
436
|
+
console.log(' asset ingest <dir> Register a provenance-carrying asset export (asset-source.json)');
|
|
437
|
+
console.log('');
|
|
372
438
|
console.log('Canon:');
|
|
373
439
|
console.log(' canon build Build dataset.jsonl + prompts/*.j2 + context/*.md from canon entries');
|
|
374
440
|
console.log(' canon freeze <id> Stamp a freeze block on an entry (--reason required)');
|
|
@@ -445,15 +511,19 @@ function printHelp() {
|
|
|
445
511
|
console.log('Examples:');
|
|
446
512
|
console.log(' sdlab init my-project --domain character-design');
|
|
447
513
|
console.log(' sdlab generate --help');
|
|
448
|
-
console.log(' sdlab snapshot create --project
|
|
449
|
-
console.log(' sdlab split build --dry-run --project
|
|
450
|
-
console.log(' sdlab training-package build --debug --project
|
|
514
|
+
console.log(' sdlab snapshot create --project my-project');
|
|
515
|
+
console.log(' sdlab split build --dry-run --project my-project');
|
|
516
|
+
console.log(' sdlab training-package build --debug --project my-project');
|
|
451
517
|
}
|
|
452
518
|
|
|
453
519
|
// All top-level command tokens users can type (including two-word heads).
|
|
454
520
|
function allKnownCommands() {
|
|
455
521
|
const oneWord = Object.keys(COMMANDS);
|
|
456
|
-
|
|
522
|
+
// SDL-L8: 'canon' is a real two-word namespace (see CANON_COMMANDS / the
|
|
523
|
+
// `namespaces` table in main()) but was missing from this list, so a typo
|
|
524
|
+
// like "sdlab cannon build" had no candidate to suggest against — every
|
|
525
|
+
// other namespace head got a "Did you mean ...?" hint, canon did not.
|
|
526
|
+
const heads = ['project', 'workflow', 'brief', 'run', 'critique', 'refine', 'batch', 'select', 'selection', 'canon', 'asset'];
|
|
457
527
|
return [...new Set([...oneWord, ...heads])];
|
|
458
528
|
}
|
|
459
529
|
|
|
@@ -515,6 +585,7 @@ async function main() {
|
|
|
515
585
|
twoWord('batch', BATCH_COMMANDS),
|
|
516
586
|
twoWord('selection', SELECTION_COMMANDS),
|
|
517
587
|
twoWord('canon', CANON_COMMANDS),
|
|
588
|
+
twoWord('asset', ASSET_COMMANDS),
|
|
518
589
|
];
|
|
519
590
|
|
|
520
591
|
// "project", "workflow", "brief", "run", "batch", "selection" two-word forms
|
|
@@ -529,6 +600,31 @@ async function main() {
|
|
|
529
600
|
}
|
|
530
601
|
}
|
|
531
602
|
|
|
603
|
+
// SDL-L2: a bare or invalid namespace verb ("sdlab workflow", "sdlab batch
|
|
604
|
+
// bogus"). These heads only exist as two-word commands — falling through to
|
|
605
|
+
// the generic COMMANDS[command] lookup below used to hand `command` itself
|
|
606
|
+
// to findClosest() against a corpus that includes that same head, so the
|
|
607
|
+
// suggester matched itself at distance 0 and printed "Unknown command:
|
|
608
|
+
// workflow" / 'Did you mean "workflow"?' — a hint that echoes the very
|
|
609
|
+
// thing the user just typed. List the real subcommands instead.
|
|
610
|
+
for (const { head, table } of namespaces) {
|
|
611
|
+
if (command === head) {
|
|
612
|
+
const subs = Object.keys(table);
|
|
613
|
+
if (!args[1] || args[1] === '--help' || args[1] === '-h') {
|
|
614
|
+
console.log(`sdlab ${head} <${subs.join('|')}>\n`);
|
|
615
|
+
console.log('Subcommands:');
|
|
616
|
+
for (const s of subs) console.log(` ${s}`);
|
|
617
|
+
console.log(`\nRun "sdlab ${head} <subcommand> --help" for details.`);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
const suggestion = findClosest(args[1], subs);
|
|
621
|
+
const hint = suggestion
|
|
622
|
+
? `Did you mean "sdlab ${head} ${suggestion}"?`
|
|
623
|
+
: `Try: ${subs.map(s => `sdlab ${head} ${s}`).join(', ')}`;
|
|
624
|
+
throw inputError('INPUT_UNKNOWN_SUBCOMMAND', `Unknown ${head} subcommand: ${args[1]}`, hint);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
532
628
|
// "critique" — bare or "critique show"
|
|
533
629
|
if (command === 'critique') {
|
|
534
630
|
if (args[1] && CRITIQUE_COMMANDS[args[1]]) {
|