@melite/models-qwen-img-edit-21 0.1.4-alpha → 0.1.5-pre-alpha
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/README.md +45 -0
- package/lib/actions.js +7 -18
- package/lib/index.d.ts +2 -1
- package/lib/index.js +65 -25
- package/lib/mods/loras.d.ts +1 -1
- package/lib/mods/mask.d.ts +1 -1
- package/package.json +2 -3
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Qwen Image Edit 2.1 — the cached-reference edit lane over the shared 2.1 checkpoint; up to 16 images, edits at the stated target resolution.
|
|
3
|
+
kind: package-library
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# qwen-img-edit-21
|
|
7
|
+
|
|
8
|
+
qwen-img-edit-21 registers Qwen Image Edit 2.1 (form `form_edit`, label "Qwen Image Edit 2.1", genre `image`): the instruction-edit lane over the SAME physical 2.1 checkpoint as the t2i sibling. The lane: UNETLoader → QwenImage21Cache (the reference-prefix KV cache wrapped around the base unet — no separate edit weights exist) → TextEncodeQwenImage21 conditioning on the anchor images through its `image_N` autogrow slots (positive AND negative from ONE node) → EmptyLatentImage at the stated target resolution → KSampler → decode and save under `<run>/edit`. This is not the 2511 lane (VAEEncode-of-source at source resolution); the branch key is the lane's `text_encode_node`.
|
|
9
|
+
|
|
10
|
+
## Params and law
|
|
11
|
+
|
|
12
|
+
Declared surface: `input_images`, `image1`, `image2`, `image3`, `reference_images`, `input_mask` (validation-only aliases the lane admits as wire keys), `prompt`, `negative_prompt`, `width`, `height`, `seed`, `steps`, `cfg`, `sampler`, `scheduler`. Laws: `width` and `height` ride together — an EmptyLatentImage takes both axes or neither, bounds 256–1536; `prompt` is required (the instruction, not a description of the image); an anchor is required — the ordered `input_images` list or a legacy spelling (`image1` / `image2` / `image3` / `reference_images`). The image cap is 16 total, anchor included (`max_images`).
|
|
13
|
+
|
|
14
|
+
Defaults: 25 steps, `euler` / `simple`, cfg 1, 1024×1024. Variants: `int8` (about 7.3 GB unet, about 24 GB VRAM, DEFAULT — provisioning required; without the 2.1 files the engine refuses loud) and `bf16` (about 14.2 GB, about 48 GB). Recipes: `remove_background` (the official template's canned prompt verbatim), `upstream_solvers`, `default`.
|
|
15
|
+
|
|
16
|
+
## Mod surface
|
|
17
|
+
|
|
18
|
+
The DECL boards `mask` only: the bare flavor whose region contract rides the crop_stitch detailer over the cached model; automatic inpainting with a named field refuses — the LanPaint sampler is 2511's lane. `./mods/loras` is the seam with an empty row set (no first-party 2.1 adapters); nothing is fetched from either subpath.
|
|
19
|
+
|
|
20
|
+
## Model Experience
|
|
21
|
+
|
|
22
|
+
### Request context and condition
|
|
23
|
+
|
|
24
|
+
A run needs the anchor image and the edit instruction; target resolution and the sampling block ride defaults. Reference sets beyond the anchor go in `input_images` order, up to the 16-image ceiling.
|
|
25
|
+
|
|
26
|
+
#### What the model sees
|
|
27
|
+
|
|
28
|
+
The anchor and reference images (up to 16), the instruction, the target resolution, and the sampling block; the cached lane above.
|
|
29
|
+
|
|
30
|
+
#### Token effect
|
|
31
|
+
|
|
32
|
+
Zero-direct: an engine graph, not a token stream.
|
|
33
|
+
|
|
34
|
+
#### KV Cache effect
|
|
35
|
+
|
|
36
|
+
Within a run, the cache is the lane's point: QwenImage21Cache prefixes reference KV around the base unet, so the edit shares context with its anchors. Across runs it stays independent.
|
|
37
|
+
|
|
38
|
+
## Known Limitations and Deferred Work
|
|
39
|
+
|
|
40
|
+
- **16-image ceiling** — beyond `max_images` the kit refuses loud; larger reference sets need trimming.
|
|
41
|
+
- **Resolution pair rides together** — a lone width or height is refused (the range rule made law).
|
|
42
|
+
- **No LoRA rows** — the `./mods/loras` seam is empty until first-party adapters land.
|
|
43
|
+
- **Live behavior unobserved** — not verified against the running model.
|
|
44
|
+
|
|
45
|
+
Exports: the plugin root, `./package.json`, `./mods/loras`, `./mods/mask`.
|
package/lib/actions.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadTextPair, decodeSave, stackLoras, orderedInputImages, regionSegs, detailerSave, isSpell, laneSampler, laneScheduler } from "@melite/comfyui-card-kit";
|
|
2
2
|
import { fireLoras } from "@melite/comfyui-card-kit/guard";
|
|
3
|
-
import {
|
|
3
|
+
import { parseDiffusionLaneFacts, parseEditCap } from "@melite/comfyui-card-kit/facts";
|
|
4
4
|
import { EDIT_DIFFUSION_BOUNDS, diffusionParamRows } from "@melite/comfyui-card-kit/paramRows";
|
|
5
5
|
/** The edit facts door: the resolved lane_inputs parsed into the
|
|
6
6
|
* closed shape. A drifted encoder class refuses here, never
|
|
@@ -10,23 +10,11 @@ import { EDIT_DIFFUSION_BOUNDS, diffusionParamRows } from "@melite/comfyui-card-
|
|
|
10
10
|
* @param raw the resolved lane_inputs (family ⊕ variant)
|
|
11
11
|
* @returns the typed facts the segment factory reads */
|
|
12
12
|
export function parseEditFacts(raw) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
const cap = raw.max_images;
|
|
19
|
-
if (typeof cap !== "number" || !Number.isFinite(cap) || cap < 1) {
|
|
20
|
-
throw new Error(`qwen-img-edit-21 edit: lane_inputs.max_images = ${JSON.stringify(cap)} — a number ≥ 1 is required`);
|
|
21
|
-
}
|
|
22
|
-
return {
|
|
23
|
-
unet: text("unet"),
|
|
24
|
-
text_encoder: text("text_encoder"),
|
|
25
|
-
vae: text("vae"),
|
|
26
|
-
clip_type: text("clip_type"),
|
|
27
|
-
text_encode_node: node,
|
|
28
|
-
max_images: Math.floor(cap),
|
|
29
|
-
};
|
|
13
|
+
// The checks + refusal prose live in the kit (J3 consolidation,
|
|
14
|
+
|
|
15
|
+
// into the family's own typed shape (B4).
|
|
16
|
+
const f = parseDiffusionLaneFacts(raw, "qwen-img-edit-21 edit", { key: "text_encode_node", node: "TextEncodeQwenImage21" }, false);
|
|
17
|
+
return { unet: f.unet, text_encoder: f.text_encoder, vae: f.vae, clip_type: f.clip_type, text_encode_node: f.node, max_images: parseEditCap(raw, "qwen-img-edit-21 edit") };
|
|
30
18
|
}
|
|
31
19
|
/** The edit action: the cached-reference lane — loaders → lora
|
|
32
20
|
* stack → text pair → per-slot LoadImage anchors →
|
|
@@ -51,6 +39,7 @@ export const edit = {
|
|
|
51
39
|
{ name: "image3", type: "string" },
|
|
52
40
|
{ name: "reference_images", type: "image_list" },
|
|
53
41
|
...diffusionParamRows(EDIT_DIFFUSION_BOUNDS),
|
|
42
|
+
{ name: "match_input_resolution", type: "boolean" },
|
|
54
43
|
{ name: "use_stock_nodes", type: "boolean" },
|
|
55
44
|
{ name: "double_reference", type: "boolean" },
|
|
56
45
|
],
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from "@deepseek-ai/cordis";
|
|
2
|
-
import type { ModelDecl } from
|
|
2
|
+
import type { ModelDecl } from '@melite/comfyui-card-kit/model-contract';
|
|
3
3
|
export declare const DECL: ModelDecl;
|
|
4
4
|
export declare const family: Plugin;
|
|
5
5
|
export { edit, parseEditFacts, type EditFacts, type EditParams } from "./actions.js";
|
|
6
|
+
export { family as default };
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.js
CHANGED
|
@@ -22,16 +22,6 @@ export const DECL = {
|
|
|
22
22
|
"width": 1024,
|
|
23
23
|
"height": 1024
|
|
24
24
|
},
|
|
25
|
-
"prompt_guide": {
|
|
26
|
-
"title": "Qwen Image 2.1 Edit Prompting Guide",
|
|
27
|
-
"sections": [
|
|
28
|
-
"GuideSection(label='Edit', body='State the change and the anchor: what stays identical. One edit per instruction.', list=[])",
|
|
29
|
-
"GuideSection(label='CFG', body='Flow-matching lane: Guidance stays low (default 1.0).', list=[])",
|
|
30
|
-
],
|
|
31
|
-
"label": "CFG",
|
|
32
|
-
"body": "Flow-matching lane: keep Guidance low (default 1.0)",
|
|
33
|
-
"list": []
|
|
34
|
-
},
|
|
35
25
|
"genre": "image",
|
|
36
26
|
// THE LANE SURFACE (fix shapes 1+2 — the model is the author of
|
|
37
27
|
// what it accepts; the card's visible_when guard list dies). The
|
|
@@ -41,7 +31,11 @@ export const DECL = {
|
|
|
41
31
|
// reference_images, input_mask — hidden carriers, but a wire key
|
|
42
32
|
// the lane admits, so the surface owns them) and THIS lane's
|
|
43
33
|
// target resolution pair — the 2.1 edit lane samples an
|
|
44
|
-
// EmptyLatentImage at stated size, so width/height are 2.1's
|
|
34
|
+
// EmptyLatentImage at stated size, so width/height are 2.1's —
|
|
35
|
+
// plus the card-owned match toggle (ON by default: output matches
|
|
36
|
+
// the anchor; OFF: the custom pair rides). The toggle is admitted
|
|
37
|
+
// on BOTH edit lanes (the 2511 lane holds it as a no-op — it
|
|
38
|
+
// always edits at source resolution).
|
|
45
39
|
// use_stock_nodes/double_reference are 2511's edit-tuning pair
|
|
46
40
|
// and are NOT here: with a declared surface the bench-write door
|
|
47
41
|
// refuses them on this family in the field's voice.
|
|
@@ -56,6 +50,7 @@ export const DECL = {
|
|
|
56
50
|
"negative_prompt",
|
|
57
51
|
"width",
|
|
58
52
|
"height",
|
|
53
|
+
"match_input_resolution",
|
|
59
54
|
"seed",
|
|
60
55
|
"steps",
|
|
61
56
|
"cfg",
|
|
@@ -149,11 +144,16 @@ export const DECL = {
|
|
|
149
144
|
"size_bytes": 675509688
|
|
150
145
|
}
|
|
151
146
|
],
|
|
147
|
+
// THE 2.1 MATRIX ON THE EDIT LANE (the variant-axis law,
|
|
148
|
+
|
|
149
|
+
// weights): Variant = Base/Turbo, Quant = int8_convrot/bf16;
|
|
150
|
+
// the quant cell owns its tier's unet spelling
|
|
151
|
+
// (CellRow.lane_inputs — the cell-lane cascade).
|
|
152
152
|
"variants": [
|
|
153
153
|
{
|
|
154
|
-
"id": "
|
|
155
|
-
"label": "
|
|
156
|
-
"hint": "The official template
|
|
154
|
+
"id": "base",
|
|
155
|
+
"label": "Base",
|
|
156
|
+
"hint": "The 2.1 base checkpoint on the edit lane — 25 steps (the official template's own count), both download tiers below, the cache-wrapped edit compose. Requires provisioning: the 2.1 files are NOT on this box by default; without them the engine validation refuses LOUD (the honest face — the 2511 weights are what ship).",
|
|
157
157
|
"group": "Variant",
|
|
158
158
|
"route": "qwen-img-edit-21",
|
|
159
159
|
"order": 0,
|
|
@@ -171,30 +171,65 @@ export const DECL = {
|
|
|
171
171
|
"dest_sub": "diffusion_models",
|
|
172
172
|
"size_hint_gb": 7.3
|
|
173
173
|
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"quant": "bf16",
|
|
177
|
+
"label": "BF16",
|
|
178
|
+
"route": "qwen-img-edit-21-bf16",
|
|
179
|
+
"vram_peak_gb": 48,
|
|
180
|
+
"lane_inputs": {
|
|
181
|
+
"unet": "qwen_image_2.1_bf16.safetensors",
|
|
182
|
+
"text_encoder": "qwen3vl_8b_bf16.safetensors"
|
|
183
|
+
},
|
|
184
|
+
"artifact": {
|
|
185
|
+
"source_url": "https://huggingface.co/Comfy-Org/Qwen-Image-2.1/resolve/main/diffusion_models/qwen_image_2.1_bf16.safetensors",
|
|
186
|
+
"size_bytes": 14230280616,
|
|
187
|
+
"sha256": "89f4158d066cc33906a199fca85634f766892dd78f49b6698dabf187ac86c4bc",
|
|
188
|
+
"dest_root": "COMFYUI_ROOT",
|
|
189
|
+
"dest_sub": "diffusion_models",
|
|
190
|
+
"size_hint_gb": 14.3
|
|
191
|
+
}
|
|
174
192
|
}
|
|
175
193
|
]
|
|
176
194
|
},
|
|
177
195
|
{
|
|
178
|
-
"id": "
|
|
179
|
-
"label": "
|
|
180
|
-
"hint": "
|
|
196
|
+
"id": "turbo",
|
|
197
|
+
"label": "Turbo",
|
|
198
|
+
"hint": "The distilled turbo weights on the edit lane — 8 steps instead of the base 25 (upstream: 'Turbo uses 8 steps'), both download tiers below, same cache-wrapped edit compose. Requires provisioning: the 2.1 turbo files are NOT on this box by default; without them the engine validation refuses LOUD (the honest face — the 2511 weights are what ship).",
|
|
181
199
|
"group": "Variant",
|
|
182
|
-
"route": "qwen-img-edit-21-
|
|
200
|
+
"route": "qwen-img-edit-21-turbo",
|
|
183
201
|
"order": 1,
|
|
184
|
-
"
|
|
185
|
-
"unet": "qwen_image_2.1_bf16.safetensors",
|
|
186
|
-
"text_encoder": "qwen3vl_8b_bf16.safetensors"
|
|
187
|
-
},
|
|
202
|
+
"resolver_defaults": { "steps": 8 },
|
|
188
203
|
"cells": [
|
|
204
|
+
{
|
|
205
|
+
"quant": "int8_convrot",
|
|
206
|
+
"label": "INT8 ConvRot",
|
|
207
|
+
"route": "qwen-img-edit-21-turbo-int8",
|
|
208
|
+
"vram_peak_gb": 24,
|
|
209
|
+
"lane_inputs": {
|
|
210
|
+
"unet": "qwen_image_2.1_turbo_int8_convrot.safetensors"
|
|
211
|
+
},
|
|
212
|
+
"artifact": {
|
|
213
|
+
"source_url": "https://huggingface.co/Comfy-Org/Qwen-Image-2.1/resolve/main/diffusion_models/qwen_image_2.1_turbo_int8_convrot.safetensors",
|
|
214
|
+
"size_bytes": 7256787829,
|
|
215
|
+
"sha256": "8144a0182964aa8403ad6dbc011db837304167d235161b9aabaa8532e967314c",
|
|
216
|
+
"dest_root": "COMFYUI_ROOT",
|
|
217
|
+
"dest_sub": "diffusion_models",
|
|
218
|
+
"size_hint_gb": 7.3
|
|
219
|
+
}
|
|
220
|
+
},
|
|
189
221
|
{
|
|
190
222
|
"quant": "bf16",
|
|
191
223
|
"label": "BF16",
|
|
192
|
-
"route": "qwen-img-edit-21-bf16",
|
|
224
|
+
"route": "qwen-img-edit-21-turbo-bf16",
|
|
193
225
|
"vram_peak_gb": 48,
|
|
226
|
+
"lane_inputs": {
|
|
227
|
+
"unet": "qwen_image_2.1_turbo_bf16.safetensors"
|
|
228
|
+
},
|
|
194
229
|
"artifact": {
|
|
195
|
-
"source_url": "https://huggingface.co/Comfy-Org/Qwen-Image-2.1/resolve/main/diffusion_models/qwen_image_2.
|
|
230
|
+
"source_url": "https://huggingface.co/Comfy-Org/Qwen-Image-2.1/resolve/main/diffusion_models/qwen_image_2.1_turbo_bf16.safetensors",
|
|
196
231
|
"size_bytes": 14230280616,
|
|
197
|
-
"sha256": "
|
|
232
|
+
"sha256": "8b74237a7f505773e2c66726fa696444b4c704585c93a347cff9044937f7914a",
|
|
198
233
|
"dest_root": "COMFYUI_ROOT",
|
|
199
234
|
"dest_sub": "diffusion_models",
|
|
200
235
|
"size_hint_gb": 14.3
|
|
@@ -275,4 +310,9 @@ export const family = {
|
|
|
275
310
|
// The family's offered actions (the atom vocabulary): the edit
|
|
276
311
|
// action the image-edit card binds.
|
|
277
312
|
export { edit, parseEditFacts } from "./actions.js";
|
|
313
|
+
// The Loader-row face: DSH loads plugin rows by bare specifier and
|
|
314
|
+
// unwraps `exports.default ?? exports` (vendor/cordis_plugins/loader
|
|
315
|
+
// unwrapExports) — the default export IS the row-loadable plugin. The
|
|
316
|
+
// named `family` stays the library face (engine loadFamilies).
|
|
317
|
+
export { family as default };
|
|
278
318
|
//# sourceMappingURL=index.js.map
|
package/lib/mods/loras.d.ts
CHANGED
package/lib/mods/mask.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@melite/models-qwen-img-edit-21",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5-pre-alpha",
|
|
4
4
|
"license": "SSPL-1.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@melite/comfyui-
|
|
23
|
-
"@melite/comfyui-card-kit": "0.1.4-alpha"
|
|
22
|
+
"@melite/comfyui-card-kit": "0.1.5-pre-alpha"
|
|
24
23
|
},
|
|
25
24
|
"devDependencies": {
|
|
26
25
|
"@types/node": "^22.20.0",
|