Spaces:
Runtime error
A newer version of the Gradio SDK is available: 6.22.0
Table Of Contents
1. Explanations
Use this file when you need to understand why kneifftools is shaped the way it
is. Use How-To User Guides for commands and
References for exact names.
2. System Architecture
System Model
kneifftools is a src-layout Python project. Runtime code lives under
src/kneiff, maintainer-only helpers live under
src/kneiff_dev, tests live under tests, and
long-form documentation lives under docs.
The main idea is simple:
pyproject.tomldescribes the package, dependencies, tools, and entry points.src/kneiffowns importable runtime behavior.testsverifies behavior from the outside where possible.docsexplains setup, workflows, exact names, and design context.justfileprovides repeatable maintainer commands.
Related links:
- Use install the package for the first setup path.
- Use project paths for exact source owners.
- Use repository routing before moving behavior.
Package Layout
The project uses a src layout so imports come from the installed package
rather than accidentally from the repository root.
Core boundaries:
| Area | Responsibility |
|---|---|
src/kneiff |
Runtime behavior and package-owned helpers. |
src/kneiff_dev |
Maintainer-only helpers. |
tests |
Behavior checks, fixtures, and regression tests. |
docs |
Longer usage, reference, and architecture material. |
docs/assets |
Tracked generated documentation figures. |
assets/*.IGNORE* |
Ignored local diagram scratch files. |
experiments/ |
Ignored local research and one-off probes. |
Keep broadly reusable helpers near the package area that owns the domain. Keep one-off diagnostics in the nearest existing tooling, test, or experiment area.
Related: use Development: source editing rules for implementation rules that preserve these boundaries.
Prompt And Resource Ownership
Prompt catalog parsing does not select a project or import an inference or training backend. The dependency direction is deliberately one-way:
project_resources ββ> prompts.catalog
β
ββββββββββββ> comfy.workflow_presets ββ> prompts.catalog
training.lora ββββββ> project_resources + prompts.catalog
comfy.lora βββββββββ> no prompt or showcase modules
kneiff.prompts.catalog.load_prompt_catalog() receives a vocabulary and an
optional overlay path. kneiff.project_resources.load_project_prompt_catalog()
owns project path validation and vocabulary loading. SimpleTuner artifact
builders receive a resolved catalog instead of reaching back into project
selection. Generic ComfyUI LoRA resolution remains independent of showcase
request types so other pipelines can reuse it without importing prompt code.
3. Configuration And Dependency Model
Configuration Model
Kneiff uses explicit files for workflow state:
- The AppRC application name is
knf.~/.config/knf/knf.apprc.tomlowns its registry of persistent storage roots;KNF_APPRC_TOMLcan point Kneiff at a different registry path. ~/.config/knf/.env.apprc-appowns app-wide Kneiff overrides.vocabulary.knf.yamlowns project identity tokens, controlled caption axes, and project-specific vocabulary layered over Kneiff's reusable JTP axes.- Kneiff's packaged core prompt catalog owns reusable prompt defaults,
character_reference, and fixed validation controls.prompts.knf.yamlis the optional project overlay for scenes and project-specific prompt choices. The resolved catalog routes rows through explicituses; Kneiff does not infer showcase eligibility. workflows/showcase_<preset>.workflow.jsonoptionally overrides a packaged showcase workflow for one project.configs/*.knf.yamlowns export and optional SimpleTuner training settings.knf project initalways createsconfigs/ANIMA.knf.yaml, the Sygred Anima training template with local component paths, andconfigs/F2K_9B.knf.yaml, the Flux2 Klein 9B template using the official base repository and unset component paths. The Flux2 config uses Sygred's 320-step profile with a fullbody/genitals warm-up; the Anima config retains its small-run settings.SOURCE/owns source images scanned by dataset sync. A new project includes0-FULLBODY/and2-HEAD/; add an anatomy-focused folder only when a project config maps it.MANIFEST.knf.xlsxowns the editable dataset index with paths relative toSOURCE/; generatedMANIFEST.yamlsits beside it for Git review.HF/<config-id>/owns public Hugging Face dataset exports. The rootHF/directory is created empty by the scaffold and ignored by Git.TRAINING/<config-id>_<run>/owns SimpleTuner run state. The rootTRAINING/directory is created empty by the scaffold and ignored by Git..old_manifests/owns archived manifest workbooks..env.apprc-storageowns machine-local AppRC overrides such asKNF_WORKERS,COMFY_MODELS_DIRfor ComfyUI showcase LoRA discovery,COMFY_LORAS_DIR_1for the interactive picker start directory, andCOMFY_UPSCALE_MODELfor server-side ComfyUI upscaling..git/,.gitignore, and.gitattributesown the new project's local Git repository and generic ignore/LFS tracking policy. The scaffold initializes amainbranch and local Git user name only for a new repository; it never creates a commit, configures a remote or email, alters global Git settings, or installs Git LFS.default_tags.txtis a project-owned seed containingkneiffplus the project's activation and species tokens. It is intentionally not runtime input to Kneiff..envowns local OpenAI-compatible caption server settings.
Resource ownership follows semantic scope, not which project first needed a resource. A caption tag or model-family workflow stays packaged when unrelated projects can reuse its meaning unchanged. Identity tokens, project-only axes, curated prompts, and workflows containing project-specific choices belong in the selected storage root. The default Anima config follows the same boundary: it uses a generic model/training recipe and packaged validation controls, while the root vocabulary and optional prompt overlay supply project identity and scenes. No Rook prompt, identity, local model path, tracker, or publishing setting is copied into a new project.
AppRC constructs one typed KneiffConfig bundle from native StorageConfig,
ComfyConfig, LmStudioConfig, and PromptgenConfig sections. Runtimeful
commands require an explicit storage selector through KNF_STORAGE or the root
--storage option. A lone registry entry is not selected implicitly. The
selected AppRC storage root is the project boundary, and Kneiff derives every
project path from the fixed scaffold above. .env.apprc-storage cannot select
that root because AppRC must resolve the selector before it knows which local
file to load. knf project use writes an app-wide fallback; shell KNF_STORAGE
and root --storage override it.
Kneiff does not use a second project descriptor such as
kneiff.project.yaml. Such a file would duplicate the storage selector and
fixed path convention without adding a separate source of truth.
Explicit config paths must remain inside the selected project root. Rejecting cross-project paths prevents one project's config from silently using another project's vocabulary or prompts.
When configuration affects a user-visible workflow, update How-To User Guides and References together.
Related: use environment variables for exact variable names and configuration files for file owners.
Dependency Model
The project separates dependency types by audience:
| Dependency Type | Owner | Audience |
|---|---|---|
| Runtime dependency | [project].dependencies |
Users who install the package. |
| Dependency group | [dependency-groups] |
Maintainers who run tests, typing, linting, docs, or profiling. |
| Lock file | uv.lock |
Maintainers or CI jobs that want reproducible uv syncs. |
This split keeps normal installs usable without requiring uv, while leaving
maintainer workflows repeatable.
Related links:
- Use install the package for install commands.
- Use dependency surfaces for exact
pyproject.tomlsections.
4. Workflow Models
Manifest-To-Export Model
Kneiff treats the source image folder as the source of truth and the export folder as disposable output.
After AppRC selects a storage root, config discovery starts from that root. A
config selector such as chroma matches files like
configs/CHROMA-2.knf.yaml case-insensitively and only auto-selects when the
result is unambiguous. Absolute config paths are valid selection inputs, but do
not bypass the required AppRC storage root and must stay inside it.
The dataset path is:
knf dataset sync configs/example.knf.yamlorknf dataset sync examplescans image files underSOURCE/.MANIFEST.knf.xlsxstores one fixed 13-row block per image. Column C owns user input; the merged columns D-H showtag,json,nlg,chroma, andproserenderings from one shared Kneifftags analysis.- Sync rewrites schema-version-2
MANIFEST.yamlwith logical identity and user input but no derived captions. - Manual annotation fills the fixed semantic fields and the
SFWcontrol. configs/*.knf.yamlmapsSOURCE-relative folders to export subsets.- Export planning selects rows, reuses their analysis, optionally resizes images,
and writes a public dataset under
HF/<config-id>/.
The config filename selects the dataset id; config content does not own paths.
Kneiff rejects source_root, manifest_path, export_root, and
allow_export_inside_source so a config cannot redirect reads or writes outside
the selected AppRC storage.
Dataset sync is dataset-only. LoRA training state is generated later by
knf train prepare or fresh knf train start under numbered
TRAINING/<config-id>_<run>/ workspaces, so manifest sync does not need
underscore-prefixed output guards.
Related links:
- Use sync a manifest workbook for the command sequence.
- Use configuration files for exact file names.
Caption Sidecar Model
Captions are rendered from the structured values in each fixed image block. This gives workbook previews, validation prompts, ComfyUI prompts, and export sidecars one semantic source.
The main pieces are:
| Piece | Role |
|---|---|
| Kneifftags built-in vocabulary | Owns reusable categories, groups, aliases, conflicts, output tags, and profile prose. |
vocabulary.knf.yaml |
Strict schema-2 extension for project identities and project-only vocabulary. |
caption_outputs |
Sets global sidecar mode, formats, and tag scope. |
caption_outputs_overrides |
Changes sidecar output behavior for one subset. |
caption |
Supplies an optional project-wide subject_sex fallback. |
Kneifftools gathers the fields in block order, omits SFW and Notes, and
calls the selected project engine once. The immutable analysis contains
resolved definitions, category membership, unknown inputs, ambiguities,
conflicts, and diagnostics. All output profiles reuse that result; no consumer
parses the row a second time.
Unknown tags are preserved through Kneifftags fallback rendering. Warnings do
not discard input, while active engine errors block activation or export. A row
marked SFW receives an additional application-level safety check because
SFW is workflow control rather than caption content.
The project extension is composed with the packaged Kneifftags vocabulary in an isolated engine. Character and species defaults use namespace-qualified inputs to prevent collisions with built-in spellings. Kneifftools reads vocabulary definitions through the public root API for prompt and field catalogs; it does not inspect Kneifftags internals.
hybrid_txt writes one .txt sidecar for each image variant. separate_txt
writes separate sidecars for selected formats. The canonical format names are
tags, natural, json, nlg, chroma, and hybrid. Removed tag and
prose aliases are rejected at the config and prompt-catalog boundaries.
tag_scope: supplemental omits tag facts already expressed by natural text
inside a joined caption; tag_scope: all keeps the complete tag tail.
Standalone tags and chroma files use all tags. Mirrored Chroma sidecars
receive the application-owned variant. prefix. Caption-text compatibility
does not make LoRA weights cross-model-compatible.
Related: use configure caption outputs for the config shape.
LoRA Workflow Model
LoRA training is layered on top of dataset sync. The same configs/*.knf.yaml file
owns both the export plan and the optional training.simpletuner block.
The LoRA path is:
- Resolve the exported dataset root from
HF/<config-id>/. This root must already be populated byknf dataset sync; training commands validate it rather than creating or refreshing it. - Resolve the run workspace as
TRAINING/<config-id>_<run>/; fresh prepare or start commands choose the next free run number. - Copy configured training subsets into the run workspace's
dataset/so SimpleTuner can write bucket metadata without touching public subset folders. - Translate
training.simpletunerinto SimpleTuner JSON artifacts under the run workspace and writekneiff-training-run.jsonasnot_started. Kneiff owns fixed names for the trainer JSON, backend JSON, optional validation prompt JSON, cache directory, and output directory. - Review the generated artifacts before launch, or resume an existing
not_startedorincompleterun withknf train start --resume. - Resolve the interpreter declared by the installed
simpletunertool, then launch Kneiff's copied patch runner in an isolated child process with environment variables prepared for the selected CUDA device. Update the run state torunning,failed,incomplete, orcompletewithout importing SimpleTuner or mutating process-global state in Kneiff. - After training, convert Chroma and Anima LoRA checkpoints to
ComfyUI-native module names when the trainer asks for ComfyUI format and
write the final validation contact sheet as
TRAINING/<config-id>_<run>-kneiff-validation-progress-grid.jpg.
A numbered workspace is valid only with its generated
kneiff-training-run.json at schema version 1. Persisted paths must be
normalized absolute paths that match the current project and remain below that
workspace. Persisted subset names must exactly match the direct dataset child
directories referenced by active image backends. Before launch, Kneiff verifies
the stored hashes and validates paths and optional prompt content from the
generated JSON itself. Run state retains only metadata deliberately excluded
from the parser JSON; it cannot override disk-owned fields. Kneiff rejects old,
edited, symlinked, or external state instead of guessing paths and rewriting
generated files.
The conversion code fuses split Diffusers-style attention LoRA tensors into ComfyUI's fused Chroma layer names and renames Diffusers-style Anima attention adapters to ComfyUI's native Anima blocks while preserving tensor data.
Related: use LoRA workflows for the commands and public interfaces for config names.
Staged T2I Pipeline Model
Solo and duo are presets over one staged runner. The runner owns job planning,
coordinate-derived seeds, queue ordering, downloads, cancellation, and the run
manifest. The public t2i_solo.run() and t2i_duo.run() functions only select
the allowed preset shape.
Prompt generation and image generation overlap deliberately. After LM Studio reviews one variation, all baseline branches for that variation are queued before the next LM request starts. Duo cleanup is a barrier stage: it begins only after every Anima baseline has completed. That ordering lets ComfyUI use one generation model stage followed by one Flux2 edit stage instead of alternating large models.
The root seed identifies an image experiment, but it does not seed LM Studio. Each image branch hashes the root seed with its stage and prompt, image, and cleanup coordinates. Adding later branches therefore cannot renumber earlier seeds. The manifest preserves sampled raw LM responses and the effective prompts after exact activation-token repair.
Participant identity remains project-owned. Slot 1 is the canonical
custom_tokens.character value; additional_activation_tokens supplies later
slots in order. CLI activation-token values affect only one run. They can
override a vocabulary slot or fill a missing slot with a warning, but the
runner never persists them.
Cancellation is based on positive ownership. Each run has a unique ComfyUI
client_id and retains every prompt id returned for its jobs. Ctrl-C deletes
only those known ids from the pending queue. It interrupts a running prompt
only after the current queue state confirms that the active id belongs to the
same set. The servers and unrelated OS processes are never stopped.
run.knf.yaml is a provenance and partial-failure record, not a checkpoint.
Atomic replacement keeps it readable after process failure, while the absence
of resume support avoids treating server queue state and local partial files as
a recoverable transaction.
Image Utility Model
Image utilities are CLI wrappers around focused package modules:
| Command Group | Model |
|---|---|
png2jpg |
Batch convert PNG files into JPEG files under an output subdirectory. |
concat |
Build quick horizontal contact sheets. |
rename |
Apply predictable file names before dataset sync. |
upscale |
Run image upscaling with selectable model weights and output settings. |
tag |
Run RedRocket/JTP-3 tagging over files or directories. |
caption |
Generate captions through an OpenAI-compatible server or BLIP/Qwen path. |
These utilities are deliberately narrow. Dataset structure and training sidecar
policy still belong to knf dataset, not the image commands.
Related: use image workflows for command examples.
5. Failure Model
Most failures become easier to debug when checked in this order:
- Confirm whether the command expects the Kneiff repository root or the AppRC-selected project root.
- Confirm the active Python executable.
- Confirm
kneiffimports from the editable install. - Confirm dependencies are installed for the workflow.
- Confirm the command is documented in References.
- Confirm the expected config files and environment variables exist.
- Re-run the smallest command that reproduces the problem.
pwd
python -c "import sys; print(sys.executable)"
python -c "import kneiff; print(kneiff.__file__)"
knf --help
Dataset-specific failures usually narrow down to one of these:
| Symptom | First Check |
|---|---|
| Missing rows | Confirm Relative_path and workbook sheets after knf dataset sync configs/example.knf.yaml --manifest-only. |
| Export validation error | Run knf dataset sync configs/example.knf.yaml --dry-run. |
| Missing captions | Check populated manual columns and the active caption_outputs config. |
| Caption server error | Check .env, BASE_URL, and OPENAI_API_KEY. |
| LoRA export or launch error | Run knf dataset sync configs/example.knf.yaml, prepare a new run, then check generated SimpleTuner artifacts and CUDA device options. |
Related links:
- Use environment problems for import and interpreter checks.
- Use command problems when a recipe fails.
- Use command reference for the expected command names.