Spaces:
Runtime error
A newer version of the Gradio SDK is available: 6.22.0
Table Of Contents
- How-To User Guides
- First-Time Setup
- Dataset Workflows
- LoRA Workflows
- Image Workflows
- Maintainer Checks
- Troubleshooting
1. How-To User Guides
Recipe Map
Use this file when you want commands in order. Use References when you need exact names and Explanations when you need the system model.
Runtimeful dataset, training, ComfyUI, and LLM examples assume that
KNF_STORAGEis exported or root--storage NAME_OR_PATHis present. An explicit workflow config path does not replace storage selection.
Related: use docs standards when adding new recipes so headings, callouts, and links stay consistent.
2. First-Time Setup
Install The Package
Use this recipe from the Kneiff repository root.
- Create or activate a Python environment:
python -m venv .venv
source .venv/bin/activate
.venv/bin/python -m pip install --upgrade pip
- Install the package for runtime use:
.venv/bin/python -m pip install -e "."
- Install the maintainer tools when you plan to edit the project:
.venv/bin/python -m pip install -e "." --group dev
- If you use
uv, sync the locked environment:
uv sync --locked --all-extras
Related: use dependency surfaces for the difference between runtime dependencies and dependency groups.
Run The First Command
Run the CLI after installation:
knf --help
Check the top-level command groups:
knf dataset --help
knf train --help
knf img --help
knf comfy --help
Related: use public interfaces for the commands and import paths users can rely on.
Configure Local Environment Files
KNF_WORKERS controls dataset export, image inspection, and the workspace copy
made by knf train prepare and a fresh knf train start. It is read from the
selected AppRC storage config and defaults to eight workers. Set it with the TUI
or the non-interactive config command:
knf --storage demo config set KNF_WORKERS 8 --scope storage
OpenAI-compatible image captioning reads BASE_URL or OPENAI_BASE_URL plus
OPENAI_API_KEY or API_KEY from .env unless you pass --dotenv-path:
cat > .env <<'EOF'
BASE_URL=http://localhost:1234/v1
OPENAI_API_KEY=not-needed
EOF
Keep secrets and machine-local project roots out of committed files.
Register A Persistent Storage Root
Use knf project init when a training project root should become a switchable
Kneiff project. It creates the Kneiff scaffold, registers the AppRC storage,
and initializes the shallow conventional layout:
demo-project/
├── .env.apprc-storage # Machine-local AppRC values, created on registration
├── .gitattributes # Git LFS tracking rules; does not install Git LFS
├── .gitignore # Ignores local and generated project outputs
├── .git/ # New main-branch Git repository
├── default_tags.txt # Project-owned seed: kneiff + identity tokens
├── vocabulary.knf.yaml
├── prompts.knf.yaml
├── configs/
│ ├── ANIMA.knf.yaml # Sygred Anima training config and local model paths
│ └── F2K_9B.knf.yaml # Flux2 Klein 9B training config
├── SOURCE/
│ ├── 0-FULLBODY/
│ └── 2-HEAD/
├── MANIFEST.knf.xlsx # Editable, created by dataset sync
├── MANIFEST.yaml # Generated Git-review sidecar
├── HF/ # Created empty and ignored
├── TRAINING/ # Created empty and ignored
└── .old_manifests/
knf project init "D:\Training\demo-project" \
--name demo \
--activation-token Character_Token \
--species-token species_token \
--git-user-name kneiff \
--yes
knf project use demo
knf project show
knf project validate
knf project list
AppRC uses the application name knf. The named-storage index lives at
~/.config/knf/knf.apprc.toml, the app-wide dotenv layer lives at
~/.config/knf/.env.apprc-app, and KNF_APPRC_TOML can override the index
path. Each registered root has a machine-local .env.apprc-storage. On
WSL/Linux, Windows drive paths are normalized before Kneiff stores or uses them.
When vocabulary.knf.yaml does not exist, knf project init requires both
--activation-token and --species-token. Omit both options when adopting a
root that already has its vocabulary. The command also creates
configs/ANIMA.knf.yaml, the Sygred Anima Base v1.0 training template, and
configs/F2K_9B.knf.yaml, the fully commented Flux2 Klein 9B template. The
Flux2 config maps fullbody, head, and genitals to their SOURCE/ folders,
uses black-forest-labs/FLUX.2-klein-base-9B with unset component paths, and
keeps the rank-32, batch-2, 320-step training settings, with a 120-step
fullbody/genitals warm-up. The Anima config continues to preserve its configured
local model paths.
default_tags.txt is a project-owned seed containing
kneiff, the activation token, and the species token. Kneiff does not consume
that file at runtime.
For a new root, the command runs git init --initial-branch main and sets the
repository-local user.name from --git-user-name (default kneiff). It
never sets an email, touches global Git config, creates a commit, configures a
remote, or installs Git LFS. Existing repositories retain their Git identity
and remotes. The generated .gitattributes declares LFS tracking rules for
images, models, archives, and workbooks, while .gitignore ignores
.env.apprc-storage, HF/, TRAINING/, and other machine-local/generated
paths. HF/ and TRAINING/ are created empty without placeholder files.
The initializer registers the root in AppRC's knf.apprc.toml and AppRC creates
the root .env.apprc-storage. Existing project-owned files are never replaced.
It is the only project initializer.
There is no separate kneiff.project.yaml. The selected AppRC storage is the
project identity, and Kneiff derives the shallow paths above in code.
vocabulary.knf.yaml overlays the packaged generic JTP vocabulary with the
project's activation token, species token, and project-only axes.
Each declared axis requires an explicit values list and each value requires a
canonical tag. prompts.knf.yaml is an optional version-1 project overlay on
Kneiff's packaged core prompt catalog. Package rows provide the portable
character reference, NOOB negative default, and fixed validation controls;
project rows provide project-specific scenes. Every row requires a nonempty
uses list such as showcase, training_validation, or negative_control.
Only the core catalog may own negative_control rows. Both loaders reject
misspelled or unsupported schema fields. Add project-specific ComfyUI overrides
only when needed as workflows/showcase_<preset>.workflow.json.
To control positive and negative prefixes during knf comfy showcase, set
defaults.showcase_model_prompts in prompts.knf.yaml. The built-in model
family keys are anima, flux2, pony, noob, z-image, and krea2.
Settings apply only to showcase generation and are not added to
training-validation prompts. A row's negative_prompt or
negative_prompts.<field> supplies the negative base; the model's
negative_prefix prepends once after that selection. negative_prefix: ""
deliberately disables only the model prefix. The old model-level
negative_prompt key is rejected. Set ignore_positive_prefix: true on a row
to submit its raw caption without any showcase positive prefix. A project
workflow named workflows/showcase_<id>.workflow.json uses <id> as its model
key unless it belongs to a built-in family.
defaults:
showcase_model_prompts:
anima:
positive_prefix: "masterpiece, best quality, "
negative_prefix: "worst quality, lowres, "
flux2:
negative_prefix: ""
pony:
positive_prefix: "score_9, score_8_up, score_7_up, "
negative_prefix: "score_4, score_3, score_2, score_1, "
noob:
positive_prefix: "masterpiece, best quality, newest, "
negative_prefix: "worst quality, lowres, "
prompts:
- id: character_reference
uses: [showcase]
negative_prompt: "blurry anatomy"
ignore_positive_prefix: true
captions: {nlg: "A character reference image."}
knf project use NAME persists the default KNF_STORAGE selector in app-wide
AppRC config. A shell KNF_STORAGE value or root --storage NAME_OR_PATH
option overrides it for a specific command:
knf --storage demo dataset plan chroma
knf project list validates every registered root. knf project show reports
the selected root, identity, validation status, default Anima and Flux2
configs, default tags, Git files and repository state, starter source
directories, and every conventional project path. knf project validate checks
the fixed starter files and source directories, parses both generated configs
through the export and SimpleTuner loaders, then parses the vocabulary, packaged
core catalog, optional project overlay, and workflow overrides and reports their
counts.
An explicit configs/*.knf.yaml path must remain inside the selected project
root. Kneiff rejects paths from another project; select that project with
--storage instead. Inspect AppRC paths and edit native config values with the
generated commands:
knf --storage demo config show
knf config paths
knf config doctor
knf --storage demo config edit
knf config edit opens the Textual TUI. knf config app init creates the
app-wide dotenv file; knf config storage add, list, and remove manage the
named-storage index. Use knf config set KEY VALUE --scope app or
--scope storage for a non-interactive override.
Keep project-local settings such as KNF_WORKERS in the project root
.env.apprc-storage, managed by AppRC.
The storage-local file cannot select its own root because AppRC must resolve
KNF_STORAGE before it knows which file to load. Use knf project use, the
shell environment, or root --storage for selection.
Set COMFY_MODELS_DIR in .env.apprc-storage, the shell, or --env-file when
using knf comfy showcase with LoRA discovery. Root --env-file options must
appear before the command group and may be repeated:
COMFY_MODELS_DIR="/path/to/comfyui-models"
knf --storage demo --env-file ./comfy.env comfy showcase
Set COMFY_LORAS_DIR_1 when the interactive LoRA picker should open in a
specific subdirectory below $COMFY_MODELS_DIR/models/loras. knf comfy upscale has built-in defaults, but you can override its model choices when
your ComfyUI install uses different filenames:
COMFY_LORAS_DIR_1="/path/to/comfyui-models/models/loras/project/version"
COMFY_UPSCALE_MODEL="4x-UltraSharpV2.pth"
COMFY_UPSCALE_REFINER_UNET="krea2_turbo_fp8_scaled.safetensors"
COMFY_UPSCALE_REFINER_CLIP="qwen3vl_4b_fp8_scaled.safetensors"
COMFY_UPSCALE_REFINER_CLIP_TYPE defaults to krea2, and
COMFY_UPSCALE_REFINER_VAE defaults to qwen_image_vae.safetensors.
If a default is not installed, interactive terminals open a picker from
ComfyUI's reported options; scripts should set the matching COMFY_* value,
pass -z for the legacy Z-Image quality workflow, or pass --fast.
Set LM Studio prompt-generation settings in .env.apprc-storage, the shell, or
--env-file when using knf llm prompt. LM Studio must already be running
with its OpenAI-compatible local server enabled:
KNF_LMSTUDIO_BASE_URL="http://127.0.0.1:1234/v1"
KNF_LMSTUDIO_MODEL="qwen/qwen3-14b"
KNF_PROMPTGEN_DRAFT_TEMPERATURE=0.7
KNF_PROMPTGEN_REVIEW_TEMPERATURE=0.2
Use KNF_LMSTUDIO_DRAFT_MODEL and KNF_LMSTUDIO_REVIEW_MODEL when the two
passes should use different local models. KNF_LMSTUDIO_CUDA_DEVICE_NAME
resolves a visible GPU name fragment, such as RTX 4070 Ti Super, for future
Kneiff-managed launch helpers; it cannot change the GPU used by an already
running LM Studio server.
When prompt exchange saving is enabled, knf llm prompt writes raw transcripts
under the selected storage root at .llm_promptgen/. Set
KNF_PROMPTGEN_EXCHANGE_DIR only when you want to override that location.
knf llm prompt saves user-facing JSON and review-text prompt results below
.llm_promptgen/results/ in the selected storage by default. Pass
--no-export to skip those result files for one run. The former --export
opt-in is removed because export is now the default.
When a command needs a config, pass either an explicit config path or a selector
such as chroma, Chroma, or CHROMA. Selectors match direct child
configs/*.knf.yaml files in the active storage root. If no selector is passed,
Kneiff auto-selects only when exactly one config is available. If multiple
configs are available in an interactive terminal, use the arrow-key picker.
Batch-capable commands let you press Space to toggle configs, a to toggle all,
and Enter to confirm; single-config commands still select the highlighted config
with Enter. In scripts, pass explicit config paths or selectors so
non-interactive runs keep failing with the available-config list.
3. Dataset Workflows
Sync A Manifest Workbook
Refresh only MANIFEST.knf.xlsx and generated MANIFEST.yaml from SOURCE/:
knf dataset sync path/to/project/configs/example.knf.yaml --manifest-only
With storage selected, use the config selector instead:
knf dataset sync example --manifest-only
Kneiff creates or updates fixed A-H workbook sheets. Every image occupies
exactly 13 rows: Relative_path, Subject, Appearance, Composition,
Pose and behavior, Face, Anatomy, Sexual content, Scene,
Presentation, Fallback, SFW, and Notes. The thumbnail in column A and
the derived tag, json, nlg, chroma, and prose outputs in columns D-H
are merged across the block. Each column-C User Input cell remains
independent.
MANIFEST.yaml is generated beside the workbook so Git can show manifest
changes clearly. Keep editing MANIFEST.knf.xlsx; the YAML sidecar is rewritten
from the workbook sync output.
When configs/*.knf.yaml files are present, run a dataset sync:
knf dataset plan path/to/project/configs/example.knf.yaml
knf dataset sync path/to/project/configs/example.knf.yaml
knf dataset sync alpha beta
Sync stages and validates MANIFEST.knf.xlsx, schema-version-2
MANIFEST.yaml, and a legacy project vocabulary before activating any of
them. The sidecar stores logical records and user input but no derived
captions. A first migration archives the previous file set below
.old_manifests/ and restores it if activation fails. Existing
_resolution_plan sheets remain available; the retired _caption_previews
sheet is replaced by the five merged output columns.
The selected AppRC storage defines the project root. The direct-child
configs/<id>.knf.yaml supplies the config id and workflow settings; source
images are read from SOURCE/, manifest rows stay relative to SOURCE/, and
the export root is HF/<id>/. Each exported dataset also gets a
kneiff-training-image-grid.jpg contact sheet, Hugging Face metadata.jsonl,
a generated dataset-card README.md, and publish-safe .hfignore and
.gitignore files in its export root. SimpleTuner files are generated by
knf train prepare, not by dataset sync.
Related: use manifest-to-export model for the ownership boundary between source images, workbook rows, and exports.
Sync A Training Dataset
Use a configs/*.knf.yaml file to map source folders to export subsets:
mappings:
identity:
- "0-IDENTITY"
details:
- "1-DETAILS"
image_resize:
min_pixel_area: 768
max_pixel_area: 1536
augmentations:
mirrored_extra: true
mirrored_transform: flip_only
seed: 12345
export_sfw_subset: true
publishing:
huggingface:
repo_id: account/dataset-name
pretty_name: Example LoRA Dataset
version: v1.0
optimized_for_model: Chroma1-HD
license: cc-by-4.0
tags: [image-captioning, diffusion-training, lora]
provenance: TODO
adult_content: false
notes: TODO
Keep filesystem paths out of this file. The config must live directly at
<project>/configs/<config-id>.knf.yaml; Kneiff derives SOURCE/,
MANIFEST.knf.xlsx, HF/<config-id>/, and numbered TRAINING/ paths. The keys
source_root, manifest_path, export_root, and
allow_export_inside_source are rejected.
augmentations.mirrored_extra adds fixed mirrored image/caption pairs during
export. Use mirrored_transform: flip_only for exact horizontal mirrors, or
mirrored_transform: augmented for the legacy mirror plus kneifftools crop,
rotation, and color jitter. SimpleTuner runtime crop settings live separately
under training.simpletuner.dataset.
Inspect the resolved paths before writing:
knf dataset plan path/to/project/configs/example.knf.yaml
knf dataset plan example
knf dataset plan alpha beta
The plan output uses Config: <id> for the selected CONFIG identity and
Config path: ... for the resolved configs/<id>.knf.yaml file.
Sync from the explicit config:
knf dataset sync path/to/project/configs/example.knf.yaml
knf dataset sync example
knf dataset sync alpha beta
Successful syncs write kneiff-training-image-grid.jpg in the export root so
you can quickly inspect the non-mirrored training images by subset. Sync also
writes Hugging Face metadata.jsonl, a generated README.md, .hfignore, and
.gitignore files. Metadata rows use relative file_name values and follow the
configured SimpleTuner training subsets when training is enabled. Exported image
and caption files are diffed against HF/<id>/.kneiff-export-state.json, so
unchanged files are skipped while README and metadata artifacts still refresh.
If that state file is missing or invalid, the next sync rewrites planned files
and preserves files outside the current plan. Use --rebuild when you
explicitly want to clear the export root.
Regenerate only the dataset card from existing export artifacts:
knf dataset readme path/to/project/configs/example.knf.yaml
Regenerate only that non-mirrored grid from the existing export directory:
knf dataset grid path/to/project/configs/example.knf.yaml
knf dataset grid path/to/project/configs/example.knf.yaml --output /tmp/training-grid.jpg
When SimpleTuner training is enabled, training.simpletuner.subsets must be a
non-empty explicit mapping. Sync reports include Train prob and Train %
columns. Train % matches the configured
data_backend_sampling mode: auto-weighting uses exported image count times
probability, while uniform uses probability only. The generated sfw subset
is excluded unless it is explicitly listed under training.simpletuner.subsets.
Sync also reports source and planned export resolution buckets plus a
source-resolution plan showing Kneiff export processing and predicted SimpleTuner
behavior from the current config. The report starts with kept vs KICKED
health counts and prints a kicked-out image table whenever any input would be
filtered by the trainer. Oversized inputs stay kept when SimpleTuner can
downsample them through maximum_image_size and target_downsample_size;
KICKED is reserved for true trainer filters such as minimum_image_size,
minimum_aspect_ratio, maximum_aspect_ratio, unsupported crop prediction, or
an unconfigured backend. This matches SimpleTuner's upstream
minimum_image_size,
maximum_image_size and target_downsample_size,
and
option
documentation. Resolution tables always include totals and preserve the smallest
buckets before aggregating other. Real sync runs list changed image files with
their source size, output size, and resize scale; add --verbose to show all
changed images and all uncapped resolution buckets.
Use --dry-run to validate and count outputs without writing files:
knf dataset sync path/to/project/configs/example.knf.yaml --dry-run
Use knf dataset describe when you want the same dry-run counts table without
the sync summary or any file writes:
knf dataset describe path/to/project/configs/example.knf.yaml
Use --rebuild only when you are ready to delete and recreate generated public
export files. Add --yes to confirm that rebuild prompt in unattended runs:
knf dataset sync path/to/project/configs/example.knf.yaml --rebuild
knf dataset sync path/to/project/configs/example.knf.yaml --rebuild --yes
--rebuilddeletes existing contents under the config-derived export root. ReviewHF/<id>/before confirming a destructive rebuild.
Configure Caption Outputs
Use caption_outputs for global sidecar defaults and
caption_outputs_overrides for per-subset changes:
caption_outputs:
mode: hybrid_txt
formats: [tags, natural]
tag_scope: supplemental
caption_outputs_overrides:
identity:
formats: [tags, natural, json]
sfw:
mode: separate_txt
formats: [tags, natural, chroma, nlg]
caption:
subject_sex: null # Set male or female only when the project needs it.
Supported caption formats are:
| Format | Output |
|---|---|
tags |
Kneifftags tag profile. |
natural |
Kneifftags natural-language profile. |
json |
Compact category-to-tag JSON derived from the shared analysis. |
nlg |
Kneifftags controlled NLG profile. |
chroma |
Kneifftags Chroma profile. |
hybrid |
Kneifftags hybrid natural-and-tag profile. |
Only the listed format names are accepted. Replace removed tag and prose
config values with tags and natural. The workbook headers remain tag and
prose because they are part of the fixed workbook layout.
Every caption for one image is rendered from the same Kneifftags analysis. Unknown inputs are preserved in fallback output and reported as warnings. Category mismatches and ambiguous inputs also remain visible in diagnostics. Active Kneifftags errors block migration or export.
Rows marked
SFWreject explicit or NSFW labels, explicit anatomy, penis state and appearance, sexual actions, sexual fluids, and the exact tagsanus,balls, andgenitals.
Set tag_scope: supplemental to keep identity and tag-only facts while omitting
tags already expressed in natural text inside a joined caption. Set
tag_scope: all when you need the full tag tail. Standalone tags and
chroma files always use the complete tag set.
Use formats: [nlg] for Flux2/Z-Image Qwen-style character LoRA captions.
Caption-text compatibility does not make LoRA weights cross-model-compatible;
train and load LoRAs within the target model family.
Project-only tags from vocabulary.knf.yaml are entered in the matching fixed
workbook field. Use Fallback when no fixed semantic field applies. A project
extension can define categories, groups, aliases, output tags, natural/NLG
phrases, and safety metadata; Kneifftags owns their validation and rendering.
Project character and species defaults are namespace-qualified so a built-in
tag with the same spelling cannot replace project identity.
caption_outputsno longer accepts per-subset mappings. Put subset-specific changes undercaption_outputs_overrides.
4. LoRA Workflows
Write SimpleTuner Artifacts
LoRA training settings live under training.simpletuner in the same
configs/*.knf.yaml file used for dataset sync.
List prepared and completed training runs:
knf train runs example
knf train runs /abs/path/to/project/configs/example.knf.yaml
Prepare the generated SimpleTuner JSON files without launching:
knf train prepare example
knf train prepare alpha beta --testrun
knf train prepare /abs/path/to/project/configs/example.knf.yaml
Run
knf dataset sync CONFIGbefore preparing training artifacts.knf train preparerequires a populatedHF/<config-id>/export with files in every enabledtraining.simpletuner.subsetsentry, and it does not run dataset sync or create an empty export root. There is no project-specific subset fallback.
The config-derived export root stays the public dataset folder. knf train prepare writes SimpleTuner state under TRAINING/<config-id>_<run>/, including
dataset/, simpletuner-config.json, simpletuner-multidatabackend.json,
_simpletuner-output/, and kneiff-training-run.json. Generated JSON reserves
paths below .simpletuner-cache/; SimpleTuner creates cache content when it
runs. When validation prompts are enabled, preparation also writes
simpletuner-validation-prompts.json. These are Kneiff-owned fixed paths;
training configs cannot rename or redirect them. Fresh preparation chooses the
next free run number by scanning existing TRAINING/<config-id>_<N>/
workspaces and root validation-grid files. Training preparation and review
output include a SimpleTuner-only resolution health summary for the copied
dataset, including kicked-out image paths when any copied image would be
filtered; random aspect crop modes list possible buckets instead of exact
counts. knf train start may create .kneiff-simpletuner/ later when the
launcher bootstraps model conversions. That directory and its generated
component directories and metadata files must not be symlinks. The only
generated link is chroma-text-encoder/text_encoder/model.safetensors, and an
existing link is accepted only when it still points to the configured Chroma
text encoder.
Every numbered workspace must contain a valid kneiff-training-run.json, and
its dataset, JSON artifacts, cache, prompt library, and output paths must match
the fixed locations in that workspace. The marker requires schema_version: 1,
normalized absolute paths, explicit typed optional fields, exact SHA-256
digests, and a nonempty unique subset list matching direct dataset/ children
from the generated data-backend JSON. Kneiff does not coerce, backfill, or
rewrite pre-layout training runs. Archive or remove an unsupported workspace
and prepare a new run.
Use training.simpletuner.curriculum when different subset mixes should train
at different points inside the same run. Phase steps are included in
training.simpletuner.trainer.max_train_steps; this example trains the
identity subset for the first 400 steps and starts every configured image
subset at step 400:
training:
simpletuner:
curriculum:
enabled: true
phases:
- name: focused_start
start_step: 0
subsets: [identity]
- name: full_mix
start_step: 400
subsets: all
Apply a short smoke-test profile from training.simpletuner.trainer_testrun:
knf train prepare path/to/project/configs/example.knf.yaml --testrun
Delay scheduled intermediary validation until an exact optimizer step with
training.simpletuner.validation_schedule.start_step. With a start step of 550
and trainer.validation_step_interval: 100, it renders at steps 550, 650, 750,
and so on. The step-0 base-model benchmark and the end-of-run validation remain
available. Omit this setting or use start_step: 0 to retain SimpleTuner's
normal interval schedule. A delayed schedule requires a positive step interval
and cannot be combined with trainer.validation_epoch_interval.
Kneiff saves the chosen step in the prepared run, so reviews, resumes, and
extensions keep that schedule even if the source YAML is changed later.
training:
simpletuner:
validation_schedule:
start_step: 550
trainer:
validation_step_interval: 100
When training.simpletuner.validation_prompts is configured, knf train prepare writes the fixed simpletuner-validation-prompts.json beside the
generated SimpleTuner config and points user_prompt_library at that file. The
clean wrapper supports direct custom prompts plus manifest-generated prompts in
one library.
Use custom for prompt text that should be copied directly into the prompt
library, from_prompts for curated captions from the selected project's
resolved core-plus-overlay catalog marked with training_validation, and
from_manifest for an activation prompt plus one sampled prompt per configured
export subset. default_negative_controls independently adds the fixed wolf
and two fixed human controls and is enabled by default. Set root styles once
to supply every enabled source; each source may override it with
caption_styles. Controls and manifest sampling require exactly one effective
style. Training config cannot redirect the project prompt source.
Custom prompts may include {activation_token}, which resolves to the selected
project's character token when the prompt library is written.
Prompt catalogs live under kneiff.prompts; SimpleTuner validation artifacts
live under kneiff.training.lora. Use positive_prefix to prepend
model-specific quality or safety tags to every generated and custom validation
prompt. Packaged controls and manifest sampling support tags, natural,
chroma, and nlg.
Generated sfw fanout rows are not added as
validation prompts unless sfw is an explicit mapping subset.
training:
simpletuner:
validation_prompts:
styles: [nlg]
positive_prefix: "masterpiece, best quality, score_7, safe, "
custom:
custom_portrait: "{activation_token}. A close-up portrait validation prompt."
from_prompts: {}
Add from_manifest with caption_styles: [tags] when sampled dataset prompts
are also needed. Set default_negative_controls.enabled: false to omit the
packaged control suite. The generated section contains fixed wolf,
residential-street, and office-worker negative controls, an activation control,
and one subset prompt per mapping.
Project prompt entries are ordered after core rows by prompt row, caption style,
and caption variant; generated prompt keys receive a runtime index prefix for
stable file explorer ordering. negative_control_species is not configurable.
Kneiff ships LoRA config templates as package resources under
kneiff.training.lora.templates: complete.yaml, chroma.yaml,
z-image.yaml, flux2-klein-4b.yaml, flux2-klein-9b.yaml, anima.yaml,
and sdxl.yaml. The
complete template is a reference for supported settings, sdxl.yaml is a full
commented Pony/SDXL starting config, and the remaining model-specific templates
are compact overlays with only model-specific caption, model, validation, and
crop recommendations.
Related: use LoRA workflow model for how Kneiff translates one dataset config into SimpleTuner artifacts.
Launch SimpleTuner Training
Launch SimpleTuner from the generated artifacts:
knf train start example --cuda-device 1
knf train start alpha beta --yes
knf train start /abs/path/to/project/configs/example.knf.yaml --cuda-device 1
Set KNF_SIMPLETUNER_EXECUTABLE in the app-wide .env.apprc-app file when
Kneiff should use a specific SimpleTuner environment instead of the first
simpletuner command on PATH:
KNF_SIMPLETUNER_EXECUTABLE=~/repos/SimpleTuner/.venv/bin/simpletuner
The configured value must be an absolute path or begin with ~, point to an
existing console script, and declare its Python interpreter directly in its
shebang. An unset or blank value preserves the PATH lookup. Kneiff uses the
selected interpreter to start the workspace's copied patch runner in an
isolated child process. It never imports SimpleTuner into the Kneiff process or
temporarily replaces the Kneiff process's working directory and environment.
Interactive terminals show a review menu before launch. Use json to inspect
the generated SimpleTuner files, diff to compare against the previous run, and
start to launch. Run-index-only path changes inside TRAINING/<config-id>_<N>/
are hidden from the diff so real generated-config changes are easier to spot.
Use --yes or --no-review when running unattended.
After a successful run, Kneiff scans SimpleTuner's validation_images, keeps
only the trained-model half of paired split validation outputs, leaves the
first-run single-image renders intact, and writes
TRAINING/<config-id>_<run>-kneiff-validation-progress-grid.jpg.
When prompt-library metadata is available, each validation column shows the
prompt key plus up to ten wrapped lines of full prompt text at both the top and
bottom of the grid.
For SDXL/Pony LoRAs, the same successful run also writes
pytorch_lora_weights.comfyui.safetensors beside each
pytorch_lora_weights.safetensors checkpoint so ComfyUI can load the exported
adapter directly.
Regenerate only that grid from existing validation images:
knf train grid path/to/project/configs/example.knf.yaml 1
knf train grid path/to/project/configs/example.knf.yaml 1 --output /tmp/validation-grid.jpg
Run the testrun profile and regenerate artifacts first:
knf train start example --testrun --cuda-device 1
Resume a prepared or incomplete run without regenerating artifacts:
knf train start example --resume 1 --cuda-device 1
knf train start alpha beta --resume 2
knf train start alpha --resume
knf train start /abs/path/to/project/configs/example.knf.yaml --resume
--resumelaunches existing generated JSON files from the selected run workspace. It does not regenerate artifacts from the current YAML config. The workspace-localdataset/copy must still exist and contain files for every active image backend. If it is missing or stale, runknf dataset sync CONFIGand prepare a new run. Pass a run number to skip the interactive prompt. Bare--resumeopens an interactive picker fornot_startedandincompleteruns. Runningknf train startwithout a selector in an interactive terminal first lists those resumable runs, then the configs that would start new runs.
Use --fallback-cuda-device when the launch wrapper should record a fallback
device for the child process environment:
knf train start path/to/project/configs/example.knf.yaml --cuda-device 1 --fallback-cuda-device 0
Showcase Training Checkpoints
Set COMFY_MODELS_DIR to the ComfyUI models root. Its models/loras
directory must be writable:
COMFY_MODELS_DIR="/path/to/comfyui-models"
Open the shared run-first picker for numeric checkpoint files from direct
training-run _simpletuner-output trees:
knf comfy showcase -t
Pass one or more positive step numbers to include only exact checkpoint directories. Every requested step must exist in at least one run:
knf comfy showcase -t 400
knf comfy showcase -t 400 800 --workflow anima
The picker first lists direct TRAINING/<config-id>_<run>/ directories. Opening
a run shows only its checkpoint-<step> LoRAs. ../ Other TRAINING runs
returns to the run list without losing checked files, so a showcase can compare
several runs. Root-level final exports are hidden because they have no numeric
checkpoint step. ComfyUI-native *.comfyui.safetensors files appear first,
followed by every remaining .safetensors file. Kneiff excludes caches, dataset
copies, symlinks, and files outside direct _simpletuner-output trees.
Use Space to toggle LoRAs or a to select all candidates. Enter selects the
checked LoRAs, or only the highlighted LoRA when nothing is checked. Each
selected file is hard-linked into a unique directory below
models/loras/.kneiff-training/ when possible and copied when the two paths use
different filesystems. Kneiff removes those temporary directories after the run,
including when workflow resolution or showcase generation fails. Omit
--workflow to infer the shared workflow from the first selected
training-relative path and open the workflow picker when the path has no unique
match.
The run and file lists keep the active row in a terminal-height-bounded viewport. Above/below indicators show omitted rows, and each rendered row is kept to one terminal line so arrow-key navigation replaces the prior frame instead of flooding a short terminal.
Kneiff prints each prompt source on its own row, followed by the inspected workflow settings and the dated ComfyUI output directory. Interactive terminals show one progress bar across every selected LoRA and eligible prompt.
Every successful showcase downloads the reported images, assembles one
timestamped JPEG in a temporary directory, and uploads it into the same dated
ComfyUI output subfolder as the individual SaveImage results. Prompts are
the columns and LoRAs are the rows, so selecting several checkpoints produces
one comparison grid. Prompt IDs and up to ten wrapped lines of full prompt text
appear above and below the images. Kneiff does not persist showcase grids below
the project's TRAINING directory.
-trequires an interactive terminal and cannot be combined with--lora.COMFY_MODELS_DIRmust describe the filesystem used by the running ComfyUI server.
Promote A Training Checkpoint
Install one reviewed numeric checkpoint as a release copy below the configured ComfyUI LoRA library:
knf train promote
knf train promote --name Rook-Preview
knf train promote uses the same run-first TRAINING picker, then lets you
browse existing directories under $COMFY_MODELS_DIR/models/loras. It asks for
a mandatory release version in v<major>.<minor> form, shows the exact target,
and requires confirmation before copying. The target name is:
<name>-<MODEL_ID>-v<major>.<minor>-<step>.safetensors
name comes from custom_tokens.character.text unless --name / -n
overrides it. MODEL_ID is the uppercase compact model ID inferred from the
generated simpletuner-config.json, and step comes from the selected
checkpoint-<step> directory. The source in TRAINING is never moved or
overwritten; an existing destination filename is refused.
5. Image Workflows
Generate Solo And Duo T2I Runs
Run LM Studio's OpenAI-compatible server and ComfyUI, then configure the
filesystem and model paths in the selected project's .env.apprc-storage:
COMFY_MODELS_DIR="/path/to/comfyui-models"
COMFY_LORAS_DIR_1="project/primary"
COMFY_LORAS_DIR_2="project/partner"
COMFY_T2I_MODEL_SOLO="diffusion_models/Krea2/krea2_turbo_fp8.safetensors"
COMFY_T2I_LORA_SOLO="primary-krea2.safetensors"
COMFY_I2I_MODEL_SOLO="diffusion_models/F2K_9B/flux-2-klein-9b.safetensors"
COMFY_I2I_LORA="primary-flux2.safetensors"
COMFY_T2I_MODEL_DUO="diffusion_models/Anima/anima-base-v1.0.safetensors"
COMFY_T2I_LORA_DUO_1="primary-anima.safetensors"
COMFY_T2I_LORA_DUO_2="partner-anima.safetensors"
COMFY_I2I_MODEL_DUO="diffusion_models/F2K_9B/flux-2-klein-9b.safetensors"
COMFY_I2I_LORA_1="primary-flux2.safetensors"
COMFY_I2I_LORA_2="partner-flux2.safetensors"
Strength keys default to 1.0. Add
COMFY_T2I_LORA_STRENGTH_SOLO,
COMFY_I2I_LORA_STRENGTH,
COMFY_T2I_LORA_STRENGTH_DUO_1,
COMFY_T2I_LORA_STRENGTH_DUO_2,
COMFY_I2I_LORA_STRENGTH_1, or
COMFY_I2I_LORA_STRENGTH_2 when a model needs another value.
For duo runs, declare participant 2 in the project vocabulary. The canonical
custom_tokens.character entry remains participant 1:
additional_activation_tokens:
- Sygred_Lightfeet
When --pipeline is omitted, knf comfy t2i solo opens an arrow-key picker
for Krea2 only, Krea2 plus Flux2 Klein cleanup, or Anima plus Flux2 Klein
cleanup. Non-interactive scripts must pass the choice. Krea2 only produces nine
finals by default; either Flux profile and duo produce nine baselines plus 27
cleanup candidates:
knf comfy t2i solo --pipeline krea2 "full-body portrait in a sunlit workshop"
knf comfy t2i solo --pipeline anima-flux2 "full-body portrait in a sunlit workshop"
knf comfy t2i duo "two characters talking beside a forest stream"
Use --num-prompts, --num-images, and --num-cleanups on Flux profiles or
duo to change branch counts. Solo Flux cleanup accepts --i2i-model,
--i2i-lora, and --i2i-lora-strength for one run. Krea2-only rejects those
cleanup options. --seed controls image branches only; LM prompt text remains
sampled.
Before each pass, Kneiff derives project identity facts, project-specific visual
concepts, and scene-relevant curated prompt references from the selected
vocabulary and prompt catalog. The LLM uses references only for persistent
identity and prompt grammar, not their scene-specific content. Every run prints
its random or explicit root seed and records the derived context plus exact raw
and effective prompts in readable run.knf.yaml.
Kneiff sends run-relative output paths to ComfyUI and uploads
run.knf.yamlthrough the same server-managed output mechanism used by the showcase grid. No client-side ComfyUI output path is required. Set optionalCOMFY_OUTPUT_DIRor pass--output-dironly to keep an additional local mirror. Any Flux cleanup also requiresqwen_3_8b_fp8mixed.safetensorsbelow ComfyUI's text encoders andfull_encoder_small_decoder.safetensorsbelow its VAE models, matching the current official distilled 9B edit workflow.
All baseline prompts are queued before Flux cleanup begins. Ctrl-C deletes only
pending prompt IDs created by this run and interrupts the active prompt only
when ComfyUI confirms that it belongs to the same run. Completed files and the
manifest remain available after failure or interruption. Krea2-only prints
Cleanup: not selected.
LM Studio and ComfyUI may allocate GPU memory concurrently. An OOM can come from either server; the command prints both URLs before generation starts.
Convert PNG Files To JPEG
Convert every PNG below a directory into an output subdirectory:
knf img png2jpg ./images --out-subdir jpg --quality 95
Preview without writing files:
knf img png2jpg ./images --dry-run
Prepare Image Sets
Concatenate images horizontally:
knf img concat ./a.png ./b.png --output contact-sheet.png --width 2000
Rename files with an enumerated random suffix:
knf img rename ./images/*.png --base-name sample --mode enum --start 1
Upscale one file or a directory:
knf img upscale ./images --out-dir ./upscaled
Interactive png2jpg and local-upscale batches replace repetitive success
lines with one Rich progress bar. Local upscale starts with a spinner while it
resolves and loads model weights, then adds the discovered image count.
Redirected execution keeps the existing plain per-file output.
Upscaling may download model weights and can use significant GPU memory.
Tag And Caption Images
Print e621-style tags from RedRocket/JTP-3:
The current RedRocket/JTP-3
mainsnapshot requires the Python packagepyvipsand nativelibvips. Install Python dependencies withuv syncor.venv/bin/python -m pip install -e .. On Fedora WSL, install the native package withsudo dnf install vips. Currentmainuses calibrated upstream tag selection;--thresholdis only for legacy pinned revisions.
knf img tag ./images --recursive
For one image, knf img tag prints only the selected tag line. For multiple
images or directory inputs, each line is PATH<TAB>TAGS.
Write .txt tag sidecars instead:
knf img tag ./images --recursive --txt
Use legacy comma-separated tag text when another workflow expects it:
knf img tag ./images --recursive --txt --comma
--csv-stdoutis a probability CSV export mode, not selected-tag text output.
Common knf img tag options:
| Option | Use |
|---|---|
--txt |
Write .txt sidecars next to images instead of printing selected tags. |
--comma, -c |
Use legacy comma-separated selected-tag text. Without this, tags are e621-style whitespace-separated tokens. |
--csv-stdout |
Print probability CSV output from JTP-3. Do not combine it with --txt or --comma. |
--threshold, -t |
Set the symmetric tag threshold for legacy pinned JTP-3 revisions. Current main uses calibrated upstream tag selection and rejects non-default thresholds. |
--device, -d |
Select the Torch device, for example cuda, cuda:1, or cpu. |
--batch-size, -b |
Set images per inference batch. |
--workers, -w |
Set upstream image-loader workers. Omit it for JTP-3's automatic default. |
--seqlen, -S |
Set NaFlex sequence length. The default is 1024; JTP-3 accepts 64 to 2048. |
--prefix, -p |
Force tag text to the beginning of selected-tag output. |
--repo-id, --revision |
Use a different Hugging Face model repository or pinned revision. |
Caption one image through an OpenAI-compatible server:
knf img caption ./image.png --server --model-name local-model
Caption a directory and write sidecars:
knf img caption ./images --server --model-name local-model --out-suffix .cap.txt
Directory captioning counts only images eligible after the existing-sidecar and
--overwrite policy. Caught server or image-open failures still advance the
attempt count and remain visible as diagnostics. Full server instruction dumps
are hidden behind an interactive bar but remain present when stdout is
redirected. Single-image captioning does not create a progress display.
knf img concat, knf img rename, and knf img tag do not show Kneiff bars.
Concatenation and renaming finish as short result-oriented operations; JTP-3 is
one upstream subprocess and does not expose reliable per-image completions.
Use the BLIP/Qwen path instead of a local server:
knf img caption ./images --blip --model-name Qwen/Qwen2-VL-2B-Instruct
Generate a two-pass image prompt through LM Studio:
knf llm prompt "Character_Token resting against a tree, rear view, looking back"
knf llm prompt prints a human review view by default with the first version,
second version, and review comments. Use --verbose or --format json for the
full structured JSON payload with dataset-shaped fields, final prompt text,
assumptions, missing input, review issues, and model ids. Use --text for a
copy-friendly prompt:
knf llm prompt "front-view portrait, smiling" --text
The explicit review format is also available when scripts should spell out the human output mode:
knf llm prompt "front-view portrait, smiling" --format review
Prompt results are saved automatically below .llm_promptgen/results/ in the
selected storage. Suppress those files when you only want terminal output:
knf llm prompt "front-view portrait, smiling" --no-export
Force known fields with repeated --field FIELD=VALUE options:
knf llm prompt "resting against a tree" \
--field character=Character_Token \
--field view=rear_view \
--field pose_body=standing,leaning
6. Maintainer Checks
Sync Dependencies
Use just sync to install the full maintainer environment from uv.lock:
just sync
Use plain pip when you only need the package and do not want uv:
.venv/bin/python -m pip install -e "."
Related: use configuration model for why runtime installs and maintainer installs are documented separately.
Run Tests
Run the focused CLI smoke tests:
.venv/bin/pytest tests/test_cli_smoke.py
Run the usual quality tools before finishing a Python code change:
.venv/bin/ruff format .
.venv/bin/ruff check .
.venv/bin/pyright
.venv/bin/pytest
Related: use Development: verification for the maintainer checklist before a commit.
7. Troubleshooting
Environment Problems
Check the active Python and import location first:
python --version
python -c "import sys; print(sys.executable)"
python -c "import kneiff; print(kneiff.__file__)"
If knf is missing, reinstall from the Kneiff repository root:
.venv/bin/python -m pip install -e "."
For image captioning, confirm the local .env contains BASE_URL or
OPENAI_BASE_URL.
Related: use failure model for the normal order of checks when a command behaves differently across machines.
Command Problems
When a just recipe fails:
- Run
just --list. - Run the underlying command manually.
- Check whether the virtual environment is active.
- Check whether the command exists in
.venv/bin.
just --list
ls .venv/bin
Related: use command reference for the expected commands and their owners.
Manifest And Config Problems
When dataset sync fails:
- Confirm the config file is named
configs/<dataset-id>.knf.yaml. - Confirm the manifest uses the canonical
Relative_pathcolumn. - Confirm
mappingsnames source folders relative toSOURCE/. - Confirm
caption_outputs_overridesnames only configured subsets, plussfwwhenexport_sfw_subset: true. - Confirm YAML keys are unique. Duplicate keys are rejected, including nested
keys such as
training.simpletuner.trainer.caption_dropout_probability. - Run sync in
--dry-runmode.
knf dataset sync path/to/project/configs/example.knf.yaml --dry-run
Related: use configuration files for the exact file owners and caption sidecar model for output behavior.