Skip to content

Krea 2 Character Creator V1.2.5 — Handbook

Trains a subject LoRA of one character on Krea 2 RAW, saves it where Krea 2 Image Creator reads it, renders the character with and without the adapter, and scores the likeness against held-out photos — one workflow, one App Mode form: name, photos, steps, Run.

Photos in → a LoRA that knows the character’s geometry → Krea 2 Image Creator’s ① Create mode needs no reference image at all — write the name in the prompt.

file what ships
SoulCraft Character Creator (Krea 2).json the one graph; opens as a form yes
character-creator-krea-2-script.sh the thin installer over ComfyUI Base: 5 model rows, one own pack, 2 pip pins yes
ComfyUI-Krea2-Character-Creator/ the node pack: five nodes and the upload JS yes (ZIP_EXTRA)
models.py every model filename, once yes
suite.py, pytest.ini the tests yes
_build/build_workflow.py the graph’s builder — never hand-edit the JSON no
_build/appe2e.py drives the real form on the pod through the DOM no
_build/character/persona.md the synthetic test character and the five-step test no

0. Read this first

The one thing that makes this work

A reference photo cannot tell a model what a profile looks like. Reference conditioning interpolates over what the photos show; a side view from frontal-only photos is extrapolation, and every model will render a confident, plausible, wrong jawline. As of September 2026 this is measured, not folklore:

  • FaithfulFaces (arXiv 2605.04702): frontal vs non-frontal reference — identity similarity drops >50%, faces “completely collapse.”
  • Mv²ID (arXiv 2603.21299): “a single-view reference provides insufficient information to preserve identity consistency across diverse facial angles.”
  • Meta-LoRA (arXiv 2503.22352) names the measurement trap: InstantID “often replicates the reference image’s pose … and can artificially inflate naive similarity metrics.”

So this package does not try. You train a LoRA once and the geometry goes into the weights.

Two kinds of character, two kinds of photos. For a real person, train on real photographs — a generated reference sheet would teach the model a stranger who resembles them from the front (the Image Creator’s handbook §0 says why). For an invented character — an AI influencer, a persona that exists only as renders — the Image Creator’s 📇 Character sheet mode makes the photo set, and the invention is the ground truth. Both arrive here as the same thing: a zip.

The training-side twin, which is easy to miss

DreamBooth3D (ICCV 2023): “DreamBooth tends to overfit to the subject views present in the training views”; ID-Booth (arXiv 2504.07392) quantified pose collapse on human faces at yaw σ = 26.12 with data that was already a semicircle of angles. That is why the sheet’s scene list spans yaw and framing, why the Character Photo Auditor measures yaw, and why the proof sheet shows four different framings rather than one.

Design rules

  1. Train on RAW, render on Turbo. Krea’s own repo: “We highly recommend using RAW for training LoRAs and applying them on Turbo for inference.”
  2. The [3398] contract is frozen. The LoRA lands in models/loras/Krea2/Subject/, the folder Krea 2 Image Creator’s 🧬 dropdown reads. Changing that path breaks another package.
  3. The name is the trigger word, once. What you type is the caption prefix, the LoRA’s filename and the word you write in the Image Creator’s prompt — byte-identical, by rule (§2).
  4. Nothing leaves the machine, and nothing prints a photograph. The nodes read the zip into memory; the face models load from the pack’s own folder; log lines carry counts only.
  5. The proof is in the form. No shell step, no second workflow: the sheet, the number and the loss curve come back where the Run button is.

Quick start

  1. Open SoulCraft Character Creator (Krea 2).json — it opens as a form. Type a Character name.

  2. Give it photos, whichever way you have them. You never pick a mode; the fields decide.

    • You have photographs → upload a zip in Your photos (zip) (the file button beside the dropdown, or drop it on the field). The Character Photo Auditor’s staging folder zips as-is.
    • You have none → leave the zip on — none — and put one clean headshot in One photo. It is restaged into 24 captioned scenes, zipped to input/<name>-sheet.zip, and trained on — all in the same Run. Add ≈ 2 minutes for the renders. Until you upload one, the field shows a plain dark square named UPLOAD-YOUR-PHOTO-HERE.png: the install writes it so the form validates on a zip run. With no zip and no upload, the sheet is rendered from that square, so upload first.

    Leave Training steps at 1000; Run. ≈ 20 minutes.

  3. Read the proof (§3). Then in the Image Creator: refresh the page once, pick the new file under 🧬 Your trained likeness, write the name in your prompt.


1. The settings, and why each one

These are the ComfyUI trainer’s real settings (comfy_extras/nodes_train.py, 0.34.5), not a recipe borrowed from another trainer. Three are correctness, not taste.

Setting Value Why
base Krea 2 RAW, the library’s own file Vendor-primary, stated three times. No token: the file is ours and nothing is gated.
network plain LoRA, rank 32 musubi’s krea2 doc says rank 32 “reproduces the model authors’ recommended default”; ai-toolkit’s global default is 32; diffusers’ train_dreambooth_lora_krea2.py defaults to 32.
alpha 1.0, fixed — and trained Not settable in core ComfyUI: TrainLoraNode hard-codes alpha=1.0 (nodes_train.py:738-740) and then requires_grad_(True) turns it on, so it is silently trained. Effective scale 1/rank, not the 32/32 other trainers use. The largest divergence from the ai-toolkit recipe; recorded, not hidden.
learning_rate 3e-4, constant Krea’s own authors recommend 3e-4 – 7e-4 with a constant schedule — verbatim in the diffusers trainer’s help text, repeated in fal’s schema. “Constant” is true by absence: core has no LR schedule.
steps 1000 (the form’s one dial) The recipe Krea’s authors are cited for is 3e-4 / ~1000 steps. Paul’s 1500-step run reached loss 0.004 — the memorisation signature. The keeper may land anywhere from ~400 to ~1200: the proof sheet is how you tell (§3).
batch_size 1 Correctness, not memory. Above 1 the sampler AVERAGES the per-image captions across the batch (nodes_train.py:206 → comfy/samplers.py:338-355) and pays B² forward passes. Raise grad_accumulation_steps instead.
gradient_checkpointing false Measured: gc-off is 3.8× faster on this GPU. It also sidesteps that checkpoint_depth=1 (the default) wraps the WHOLE DiT in one segment (nodes_train.py:437-472) and saves nothing. If you ever turn it on, use depth 2.
optimizer / loss AdamW / MSE Core’s defaults; plain AdamW is the configuration under which the known Krea 2 training bugs disappear.
dtypes bf16 training, bf16 LoRA What the 96 GB card runs at 1.16 s/it.
resolution long edge 1024, aspect kept, never cropped Every photo is scaled by the zip node before the DiT; the first real run at native phone resolution OOM’d a 96 GB card at step 0. Mixed sizes are the normal case: each photo travels as its own tensor.
intermediate saves none — one run, one LoRA Core has no save_every. Two step counts are two runs, two proof sheets.
seed 42, fixed Reproducible; the proof seeds are 42–45.

Measured on the first real run (2026-09-07, 20 captioned photos, 9 distinct sizes, RTX PRO 6000 96 GB): 1.16 s/it steady after a ~3 s/it warm-up (read the rate at step 100+), so 1000 steps ≈ 20 min; ~87.5 GB peak, stable once every photo size had been seen. Loss 0.44 at step 4 → 0.09 at 138 → 0.004 at 600.

The proof recipe is Comfy-Org’s own Krea-2 Turbo template (image_krea2_turbo_t2i.json): KSampler, euler/simple, 8 steps, cfg 1.0, denoise 1, 1024², no ModelSampling node. Four scenes, the same seeds and words with and without the adapter.

Guards, and the bugs behind them

  • The saver refuses an adapter that learned nothing. In ComfyUI the zero-initialised factor is lora_down (the mirror of kohya’s lora_B); the saver counts modules where BOTH factors are non-zero and raises when there are none. A no-op adapter loads fine and looks exactly like a bad dataset.
  • The 19-widget guard. TrainLoraNode’s seed declares no control_after_generate, yet the graph carries 19 widget values with "fixed" at index 8 — correct only because frontend 1.49.6 falls back on the widget’s NAME. A comfyui test reads core’s schema and pins the count, so the day that changes a test says so instead of training_dtype silently becoming "fixed".
  • Every caption starts with the name. A .txt that already has it is left alone; one without it is prefixed; a photo with no .txt gets "<name>, a photo of a person". Counts are logged, never the text.

2. Your photos, and the zip

Two routes in, and no switch to set. A zip trains on that zip. The zip left on — none —, with one photo in the One photo field, renders a character sheet first and trains on that. use_sheet is an output of the zip field itself, so the two can never disagree, and the route you did not take is lazy — a zip run never loads the identity adapter and never renders a frame.

The generated sheet still writes input/<name>-sheet.zip before training starts, so the Character Photo Auditor can measure the set, and a later run can retrain on exactly those photos without paying for the renders again. The folder tree itself lands in output/krea2cc/sheets/<name>_NN/ by default; [35].output_folder (a canvas widget since V1.2.0, not a form field) moves it to another folder under output/.

Honest limit, measured on the pod 2026-09-08. The 24-scene list asks for eight profile frames and five full-body ones; the auditor found no left profiles and no full-body frames in a real sheet. Restaging one anchored photo holds framing far better than it holds yaw. More words in the scene list will not fix it — the open question is the engine, and it is written up in HANDOFF.md. If you have real photographs, use them: a generated sheet is the fallback, not the better input.

The name. Lowercase letters, digits and underscore, 3–24 characters, starting with a letter — vesperq, not anna. A common given name carries strong priors in the text encoder and you fight them for the whole run. The same rule is enforced by the Character Photo Auditor and by the Image Creator’s 📇 mode, so the name travels unchanged: caption prefix → zip name → LoRA filename → prompt word.

The zip (written by the 📇 Character sheet and by the Character Photo Auditor’s staging folder; easy to make by hand):

inside the zip what happens
images at the top level, or under train/ (or any other folder) trained on — .png, .jpg, .jpeg, .webp
NNN.txt beside NNN.png its caption; the name is prefixed if it is not already there
holdout/ never trained on — the likeness test’s references (§3). Four or five frames spanning angles
rejected/, unmeasured/ skipped (the auditor’s folders; their .txt files are reasons, not captions)
__MACOSX/, ._*, .DS_Store ignored

EXIF rotation is applied; the long edge is scaled to 1024; nothing is cropped.

What a good set looks like. Front-only failure is usually a framing prior, not a face problem: if every photo crops at the chest, the trigger learns “chest-up composition”. Shoot — or, for a sheet, render — profile left and right, three-quarter left and right, looking up and down, real full-body frames, two lighting setups, two backgrounds. 25–40 for training, plus 4–5 held out. Captions describe what you don’t want learned — framing, angle, expression, hair, clothing, lighting, background — and omit face structure, eye colour, skin tone and build. “You cannot caption your way out of missing variety.”

Run the Character Photo Auditor first on real photographs. It measures yaw and framing, captions locally, picks the holdouts, and stages train/ + holdout/ in exactly this layout. It costs nothing; a training run costs money and twenty minutes.


3. Reading the proof sheet and the likeness number

The form’s first output is one image, three rows:

row what it is
references the zip’s holdout/ photos — the trainer never saw them. If the zip had none, the training photos stand in and the report says so (then the number is likeness to what it trained on, which is a weaker claim)
with the LoRA four scenes naming the character, on Turbo; each thumbnail carries its cosine to the references’ mean
without the LoRA the same seeds and words with no adapter — what the words alone draw

The report’s first line is the number and the verdict, then the control’s score, the copy check, and where the LoRA was saved.

The number. InsightFace ArcFace cosine (buffalo_l, normed_embedding, largest face, BGR), computed on the pod, between each render and the normalised mean of the references — never a single reference, which would measure likeness against one angle and call it identity.

The bands are judgements, recorded as such. Real photos of one person score ~0.90 ArcFace cosine; published identity-preserving generators land 0.6–0.8 (PuLID 0.733, InfiniteYou 0.752); above ~0.85 on GENERATED images is a memorisation warning, not an achievement (DreamBench++: “a negative correlation between concept preservation and prompt following”).

likeness verdict
< 0.45 not learned — check the captions carry the name and the photos show the person
0.45 – 0.85 learned
> 0.85, or copy check > 0.92 memorising — try fewer steps

The copy check is the highest cosine from any render to any single training photo. Near 1.0 means the LoRA is pasting a photo — its background and clothes will follow the character into scenes that asked for something else. Below the reference score is what you want.

The control should sit near 0.1–0.3: a stranger who matches only the words. If it climbs, the base model already knew the name — pick a stranger one.

Two step counts are two runs. Compare their sheets; run 700 if 1000 memorises.


4. Where this runs

VRAM. 88 GB minimum, measured (the LoRA training peaks at ~87.5 GB): in practice a 96 GB card.

Decision, 2026-09-07: RunPod. Paul’s call, made with the trade-off in front of him. This section used to require a GCP confidential VM, and the argument below is kept because it is still true. What changed is the decision, not the facts.

This is the only package that touches the photographs, so it is the only one with a venue requirement — which is exactly why the change is recorded rather than quietly applied.

What was given up:

GCP g4 confidential RunPod
GPU memory encrypted + attested ✅ ✗
CPU memory encrypted ✅ (plain SEV, no integrity) ✗
Kernel dedicated VM shared host kernel
tmpfs pages inside the encrypted boundary host page cache
Provider licence over your content none granted ToS §5 grants one
Attestation before the key moves ✅ not applicable

The photographs did not stop being the protected asset. They are simply less protected. RunPod’s ToS §5 grants them “a licence to… use Your Content in an aggregated and anonymized form to update and improve the Service”, and it is container-based — shared host kernel, so tmpfs pages are host page cache. A confidential G4 Spot instance was $1.78/hr against RunPod’s $2.09 on 2026-09-06; the price was never the reason.

The GCP lane (lane.sh, attestation before the key moves, the age ciphertext path) was deleted in V1.0.0 rather than kept dormant — an unused security path drifts, and git history has it (git show 04fcc07:"character-creator-krea-2/lane.sh") if the venue ever moves back.


5. Sibling boundary

Owner Files
This package the trainer graph, its node pack, its models.py rows
Krea 2 Image Creator its graph, script, suite and models. The 📇 Character sheet moved here in V1.1.0 and is no longer one of its modes
Shared, frozen [3398] LoraLoaderModelOnly reads models/loras/Krea2/Subject/; the trigger rule; the zip layout (§2); the four Krea 2 model rows, byte-identical

The boundary was lifted for one piece of work on 2026-09-07 (the sheet mode there, V1.6.0, by Paul’s instruction) and stands again. HANDOFF.md carries the contract and what is still open on the other side.

Does this hit the outcome?

“Photos in, a LoRA Krea 2 Image Creator can use.” Yes, with no shell step: the saver writes into the frozen folder under the character’s name, the file loads through LoraLoaderModelOnly’s generic diffusion_model.* passthrough (the same key names core’s trainer writes), and the comfyui tier pins the schemas this graph relies on.

“Output the character, and test accuracy.” Yes, in the form: four renders with the adapter beside four without, and a number against held-out photos. What the number means is §3, and it is a judgement — no test here can tell you whether a LoRA looks like someone.

“The highest quality LoRA we can get for Krea 2.” Not claimed. Every value traces to a primary source; no A/B between trainers on Krea 2 exists, and the escalation ladder if a run disappoints is in §6.


6. What is NOT proven — stated so nothing reads as settled

  • Likeness bands are judgements. 0.45/0.85 come from published identity-preservation numbers on other backbones and one measured Krea 2 run, not from a Krea 2 study.
  • No comparative likeness evidence between any two trainers on Krea 2. Core ComfyUI’s trainer is used because it is first-party and runs inside the UI; nobody has A/B’d it.
  • No first-party Krea hyperparameters. The 3e-4–7e-4 range reaches us via diffusers’ and fal’s attribution to “the Krea 2 authors.”
  • alpha fixed and trained (§1) is a divergence nobody has measured the cost of.
  • The character sheet’s renders inherit the identity engine’s geometry. For an invented character that is the character. For a real person it is a stranger (§0).
  • Realistic ceiling, from the one candid first-hand Krea 2 person-LoRA report found: “Body consistency is very good. Face consistency is acceptable. Some generations still deviate.”
  • Escalation ladder if a run disappoints: fewer steps (700) → more and better photos → a second sheet with different scenes → attention-only at rank 64 → a different base (Qwen-Image, Apache-2.0).
  • No test here renders or trains. The pod pass (_build/appe2e.py) is the proof; the suite proves structure, and exercises the five nodes on synthetic frames.

Krea 2’s Community Licence permits commercial use under $1M revenue, requires content moderation (§4.2) and AI disclosure (§4.3), and its AUP bans publicity/digital-replica violation. Training on yourself, or on a character you invented, under $1M, is inside the grant.

InsightFace’s buffalo_l weights are non-commercial research use only (MIT covers the code, not the weights). They run the likeness test and nothing else; Paul’s use is non-commercial.

A subject LoRA of a real person carries an obligation — train only on people who have consented, and that includes you deciding where these images go.


8. The suite, and the front door

Terminal window
bash "character-creator-krea-2-script.sh" test # everything runnable here
bash "character-creator-krea-2-script.sh" test own # one tier

114 test functions across 14 tiers, the base’s 42 canvas tests included. Every test proves structure or exercises a node on synthetic frames; none trains or renders.

tier what it proves
static RAW trains and Turbo renders; the two proof samplers differ only by the LoRA; batch 1 and the §1 settings; named widgets agree with positional; wired end to end; every link runs left to right; every type core or ours
contract the four shared rows are byte-identical to the Image Creator’s; the installer table is generated from models.py (face-pack row included); the frozen Krea2/Subject folder; no third-party packs, exact pip pins
own the pack ships whole and installs before the restart; no network, subprocess or eval; the name rule; the zip layout (train/, holdout/, rejected/, junk, 1024, captions); the saver (metadata, never overwrites, refuses a dead adapter); the proof prompts; the likeness maths; the contact sheet; detection + recognition only; the alignment port
face the scorer’s real path, on this machine: SCRFD finds the face, the ported _estimate_norm aligns it, ArcFace embeds it, and the number means what the report says — the same face against itself is ~1.0 and two different people fall below the 0.45 band. Runs on insightface’s own test photograph against the buffalo_l pack this Mac already has. Added 2026-09-08: until then the likeness maths was proven on synthetic vectors and its actual path ran nowhere but the pod
app what the REAL frontend renders, not what the JSON declares: the file opens in App view (the graph canvas reports a 0×0 rect), all three fields are on screen WITH their help lines, the zip field reads — none —, and this pack’s own nodes register. Added 2026-09-08 — until then every App Mode test here read the JSON, and the pod was the first thing ever to open this form
appmode linearMode opens the form; exactly three fields in order; the character leads the four outputs at full size; the zip field uploads through the panel’s own control (a declared button is not drawn — measured); labels on the host slots; help fits the column; outputs live terminals; labels did not rewire anything
privacy no print carries a caption or an archive filename; only the saver writes
install every download can fail by name; a clean run files every row (the face pack inside the pack’s folder), installs the pack, syncs the graph; the V0.7.0 loader is removed; --check writes nothing
docs the record names this version; what is not proven; the venue decision; the zip contract and the bands match the code
package reproducible from the builder; python compiles without warnings; scripts parse; the zip matches the tree
comfyui against a real checkout: every core type registered; TrainLoraNode’s 19 widgets in order; the other signatures
uiux · snapshot · config the base’s canvas kit

8.1 App Mode — the front door

field host help
Character name [19].name the trigger word, lowercase 3–24
Your photos (zip) [20].zip_file — a combo flagged image_upload, so the panel draws its own file button beside the dropdown a character sheet, or upload a zip
One photo (no zip only) [21].image only if you have no zip
Training steps [40].steps 1000 ≈ 20 min · fewer if it copies

Outputs, in order: the character — the twelve renders with the LoRA, full size — [83], the proof sheet [81], the report [82], the sheet’s own report [35] (its output_folder widget chooses where the sheet tree is written), the loss curve [51]. The same four seeds without the LoRA are saved beside them (krea2cc/control) but are not a form output; the sheet shows them.

The rendering contract (frontend 1.49.6, measured; unchanged through 1.54.6): the label is widget.label || widget.name and lives on the host node’s INPUT SLOT (linearData’s config has no label field); the description is one line, truncated at ~40 characters; App Mode draws only a LIVE node’s widgets; pruneLinearData drops an unresolvable entry silently; the help line shows about 34 characters in the panel’s column. The upload, measured on the testbed’s real frontend (2026-09-07): a button widget declared in linearData is resolved but not drawn — so the zip combo carries image_upload, which makes the panel draw its own file button and hidden file input on that row, and the pack’s JS retargets that picker to .zip by the row’s data-widget-key; /upload/image stores any file, the field then reads the zip’s name (proven: _build/snapshots/e2e/02b-steps-blocked-upload.png). Every field is also wrapped in a DropZone bound to the node’s onDragOver/onDragDrop, which the JS installs. On the canvas the node keeps one labelled ⬆ button. The zip combo ships — none — so the graph validates before any upload.


9. Record

version date what
V1.2.3 2026-10-16 Every Hub row is pinned to a commit. ComfyUI Base 3.12.0 honours the revision in a row and checks each Hub file against the sha256 the Hub states for that commit, once, at download, so a repo that moves or renames a file upstream can no longer 404 a row or change what installs (the H3 latent upscaler broke that way on 2026-09-17). The five Hub rows name the commit base.sh gen-models <dir> --pin printed on 2026-10-16 (Comfy-Org/Krea-2 at 1171f4d, Comfy-Org/Qwen3-VL at 02f0d3e, conradlocke/krea2-identity-edit at 89e9e7a), from models.py’s new REV table, the same commits as the Krea 2 Image Creator’s so the shared rows stay byte-identical; each file’s size and Hub sha256 are unchanged. The InsightFace row is a GitHub release asset and stays as it is. Files already on a volume are kept as they are: no download and no re-hash. BASE_MIN is 3.12.0, because an older base drops the revision and fetches main. No graph change but the version stamp.
V1.2.4 2026-10-16 BASE_MIN 3.17.1, coach_tour, and two tests that skip instead of branching. The base marks the App Mode tour seen on install (3.17.1), so the form opens clear; _build/appview.py and _build/appe2e.py call the base’s coach_tour instead of their own Skip/Close clicks and stop when a tour opens on a seeded server. test_contract_installer_table_matches_models_py (the Photo Auditor sibling) and test_package_every_shell_script_parses_and_is_executable (the checkout’s modes and its zip) checked their repo-only part behind an if, so a run from the extracted zip passed without it; each now SKIPS when that part is missing, and CI’s VERIFY_SUITE=zip runs it again from the repo (error log row 106). Geometry only: comfyui-krea2edit v2.0.0 (upstream, 2026-10-16) appends two widgets (ref_position, ref_position_a, defaults = the old placement) to Krea2EditModelPatch, which the CI testbed draws at the pack’s HEAD, so [26] is now 294 high (the pinned 86f886d draws three widgets in it) and the three grounded encodes below it move down 50; _build/sizes.json re-photographed. The pin is unchanged.
V1.2.5 2026-10-17 GPU_MIN_GB for the site’s catalog. GPU_MIN_GB="88", measured: the LoRA training peak (~87.5 GB on a 96 GB card) is the smallest card the default flow runs on, and the site’s catalog reads it. No graph change but the version stamp.
V1.2.2 2026-10-16 The photo [21] names is on the pod. [21] ships pointing at UPLOAD-YOUR-PHOTO-HERE.png, and a live LoadImage whose file is not in input/ makes ComfyUI’s validate_prompt reject the whole prompt, so on a pod without Krea 2 Image Creator (whose install wrote that file) a zip run was refused at Run. Nothing here wrote it since V1.1.0 introduced the name. pkg_pre_models now writes it: 512 x 512, one dark colour, byte-identical to the Image Creator’s, never over a file already there; --check only reports it. One install test pins the name, the bytes and the keep-what-is-there rule. No graph change.
V1.2.1 2026-10-16 No monorepo leftovers. The script’s repo discovery looked for base/testbed.sh, a monorepo path gone since the base became a submodule; in its own repository (2026-10-16) the line is removed and the script reaches the base through $COMFY_BASE alone. The suite’s by-hand line reads $COMFY_BASE/py, and the skip reason for a missing ComfyUI checkout names $COMFY_BASE/testbed.sh. No graph change.
V1.2.0 2026-10-01 The sheet folder is a workflow choice. Krea2CCSheetZip ([35]) gains an optional output_folder widget (default krea2cc/sheets, relative to output/, no .., blank means the default), so a workflow chooses where the sheet tree lands without anyone editing the pack; the App Mode form is unchanged. The pack’s text names no person and points at no record a buyer does not have. One new unit test.
V1.1.0 2026-09-09 📇 The character sheet moved in from Krea 2 Image Creator, by Paul’s decision: the sheet makes training data, so it belongs beside the trainer that eats it, and the Image Creator’s new front door is a prompt and two photos with no room for a name field that meant nothing in five of six modes. No mode switch here either — a zip trains on the zip, — none — plus one photo renders 24 scenes and trains on those, and the branch not taken is lazy. Costs the one third-party pack this package had avoided (comfyui-krea2edit, pinned to v1.2.5) and the 1.83 GB identity adapter, byte-identical to the sibling’s row so the ledger fetches it once. The proof sheet widened 4 → 12 scenes — five yaws, three pitches, five framings — because four level, mostly frontal frames proved nothing about profile or full-length likeness; and contact_sheet now WRAPS at six columns, which it had to before twelve cells drew a 3176 px band. target_latent is wired on the edit patch, which the pack’s own tooltip asks for and the sibling’s graph omits.
V1.0.5 2026-09-08 BASE_MIN says what this package actually needs. It said 2.0.37 while the shared insightface/buffalo_l.zip row is only legal on 2.0.39+ — the freeform category that lets the row carry an empty Family lives there — so on a pod running an older base the install fails with “buffalo_l.zip needs a Family”. The Character Photo Auditor hit exactly that with the identical row and warned this package before it could. It is now 2.0.40, which also carries the restart fix: on this pod the custom nodes import for over three minutes and the old 180 s window failed the install outright. The rule behind it, recorded in the base’s handbook: a shared rule and its consumers move together, so anything that adds a category or a row format raises BASE_MIN in the same breath.
V1.0.4 2026-09-08 A truncated face pack is no longer mistaken for a good one. The three model files must each be at least 100 KB before the pack counts as present, not merely exist. It matters because the folder is now shared: insightface’s own guard returns early when the DIRECTORY exists, so an interrupted extraction leaves a tree the library treats as complete forever, and with two packages unzipping into one place either can be the one interrupted. The floor and the reasoning are the Character Photo Auditor’s, adopted here so both packages fail the same way.
V1.0.3 2026-09-08 The face pack is shared, and a second training no longer runs out of memory. (1) buffalo_l.zip moves to models/insightface/, a freeform category neither node pack owns: the Character Photo Auditor needs the same 288 MB release asset, and ComfyUI Base’s ledger files one filename at one destination, so it was being downloaded twice and the base’s own suite was red on the conflict. Agreed with that package’s session on 2026-09-08; both rows now match, each suite checks the other’s, and the node reads the shared folder (an install made before the move keeps working — this pack’s own models/ is still read). (2) The saver frees ComfyUI’s models after writing the adapter. Measured on the pod: a first training of 24 images at 600 steps ran in 23.5 minutes and the second died with Allocation on device 0 would exceed allowed memory, because RAW, the text encoder and the VAE were all still resident. Comparing two datasets is the normal way to use this package. The LoRA is on disk before the free, and a failure to free never loses it.
V1.0.2 2026-09-08 Three findings from the sibling packages, and the pipeline proven on the Mac. (1) _fit is integer arithmetic: int(w * (max_side / long)) truncated 1601 → 1023 → 1008 after the stride, for about one long edge in eight (Character Photo Auditor HANDOFF §3); a test pins 1601 → 1024. (2) The zip combo is LAST in INPUT_TYPES and max_side first: ComfyUI Base’s combo check inserts the frontend’s upload slot after any image_upload combo and judges the stored widgets_values by position, so any widget stored after the zip would be read in the upload slot’s place and end the install FAILED (measured by the auditor on the pod, HANDOFF §4a). The App form’s order is linearData’s and does not change. (3) Root CLAUDE.md §4.6, the pipeline: a comfyui test saves an adapter through this package’s own saver and hands the file to ComfyUI’s own comfy.lora.load_lora — the loader the Image Creator’s [3398] uses — then checks the path lands under the folder that node’s dropdown lists.
V1.0.1 2026-09-08 The character is the first output. The four renders WITH the LoRA are saved full size ([83], krea2cc/render) and lead the form’s outputs; the same seeds without it are saved beside them ([84], krea2cc/control, not a form output). Both sit under the report in column ④: putting them under column ③’s decoders grew the canvas past the kit’s Mpx-per-node budget (0.325, measured on the pod). Installed green on the pod (6 packs import, 76 passed) — the form pass is what V1.0.1’s record still owes.
V1.0.0 2026-09-07 One workflow: name, photos, steps, Run → LoRA + proof sheet + likeness score. The chooser workflow, the ai-toolkit Trainer.sh, the GCP lane.sh and scorer.py are deleted (Paul: delete, consolidate, edit). The one node became a pack of five (ComfyUI-Krea2-Character-Creator, publisher Generate-AI): the name (the shared trigger rule), the zip reader (now with holdout/, rejected/ and the caption rule), a saver that writes into models/loras/Krea2/Subject/<name>_<steps>steps.safetensors directly — no keep command — with safetensors metadata and a refusal of all-zero adapters, four proof prompts with fixed seeds, and Krea2CCLikeness: InsightFace ArcFace cosine on the pod against the held-out photos, a three-row contact sheet and a report with the number. The face pack is a ledger row inside the pack’s folder (insightface’s own release asset, 288,621,354 bytes); insightface/onnxruntime ride as PIP_EXTRA. The zip uploads from the App panel — not through a declared button (measured: the panel resolves it and does not draw it) but through the panel’s own image_upload control on the zip combo, retargeted to .zip by the pack’s JS; no frontend upgrade needed. Drag-and-drop onto the field too. The graph is WF_NAME now, so the base’s sync, smoke and combo checks cover it (V0.7.0’s trainer had none); hook failures reach BASE_FAILED; the zip combo ships — none —. steps defaults to 1000. The Image Creator gained the 📇 Character sheet mode (V1.6.0) in the same session, writing input/<name>-sheet.zip for this form.
V0.7.0 2026-09-07 Training moved into ComfyUI, and the venue protection was given up. Core ComfyUI’s training stack (MakeTrainingDataset → TrainLoraNode → SaveLoRA) did the whole job from a second workflow; one own node (Krea2CCLoadZipDataset) got the zip in. The first run on real photographs OOM’d at native phone resolution; the node scales the long edge to 1024. First real run: 20 photos, 1.16 s/it, ~87.5 GB peak. Three settings are correctness: batch 1 (captions averaged above it), gc off (checkpoint_depth=1 wraps the whole DiT), alpha fixed and trained. The venue moved to RunPod (§4). Base 2.0.37’s PKG_RESTART_WHY exists because the node sat unregistered under a green report.
V0.6.0 2026-09-06 The scorer scored (held-out anchor, paired deltas, a band not a maximum) and ai-toolkit was pinned to 7690ea62. Both now superseded: the likeness test lives in the graph.
V0.5.0 2026-09-06 The GCP lane became runnable; lane.sh doctor. Deleted in V1.0.0 with the venue decision.
V0.4.0 2026-09-06 The scorer, and the AdaFace/InsightFace colour-order correction: both expect BGR.
V0.3.0 2026-09-06 The confidential lane, in the order that is the security property.
V0.2.0 2026-09-06 The ai-toolkit trainer could never have completed a run (checkpoints one folder deeper than it looked); lr 1e-4 → 3e-4, steps 3000 → 1500. The package became installable on ComfyUI Base.
V0.1.0 2026-09-06 Package created from the sibling split.