Spaces:
Runtime error
Runtime error
File size: 54,521 Bytes
2857cf3 ae10cda 2857cf3 09df1fe 2857cf3 09df1fe 2857cf3 09df1fe 2857cf3 09df1fe 2857cf3 09df1fe 2857cf3 09df1fe 2857cf3 09df1fe 45f194e 09df1fe 2857cf3 09df1fe 2857cf3 09df1fe 2857cf3 09df1fe 2857cf3 09df1fe 2857cf3 09df1fe 2857cf3 ae10cda 2857cf3 ae10cda 2857cf3 ae10cda 2857cf3 ae10cda 2857cf3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 | <!-- ======================================================== -->
## Table Of Contents
<!-- ======================================================== -->
1. [How-To User Guides](#1-how-to-user-guides)
1. [Recipe Map](#recipe-map)
2. [First-Time Setup](#2-first-time-setup)
1. [Install The Package](#install-the-package)
2. [Run The First Command](#run-the-first-command)
3. [Configure Local Environment Files](#configure-local-environment-files)
4. [Register A Persistent Storage Root](#register-a-persistent-storage-root)
3. [Dataset Workflows](#3-dataset-workflows)
1. [Sync A Manifest Workbook](#sync-a-manifest-workbook)
2. [Sync A Training Dataset](#sync-a-training-dataset)
3. [Configure Caption Outputs](#configure-caption-outputs)
4. [LoRA Workflows](#4-lora-workflows)
1. [Write SimpleTuner Artifacts](#write-simpletuner-artifacts)
2. [Launch SimpleTuner Training](#launch-simpletuner-training)
3. [Showcase Training Checkpoints](#showcase-training-checkpoints)
4. [Promote A Training Checkpoint](#promote-a-training-checkpoint)
5. [Image Workflows](#5-image-workflows)
1. [Generate Solo And Duo T2I Runs](#generate-solo-and-duo-t2i-runs)
2. [Convert PNG Files To JPEG](#convert-png-files-to-jpeg)
3. [Prepare Image Sets](#prepare-image-sets)
4. [Tag And Caption Images](#tag-and-caption-images)
6. [Maintainer Checks](#6-maintainer-checks)
1. [Sync Dependencies](#sync-dependencies)
2. [Run Tests](#run-tests)
7. [Troubleshooting](#7-troubleshooting)
1. [Environment Problems](#environment-problems)
2. [Command Problems](#command-problems)
3. [Manifest And Config Problems](#manifest-and-config-problems)
<br>
# 1. How-To User Guides
<!-- ======================================================== -->
## Recipe Map
<!-- ======================================================== -->
Use this file when you want commands in order. Use
[References](References.md) when you need exact names and
[Explanations](Explanations.md) when you need the system model.
> [!IMPORTANT]
> Runtimeful dataset, training, ComfyUI, and LLM examples assume that
> `KNF_STORAGE` is exported or root `--storage NAME_OR_PATH` is present. An
> explicit workflow config path does not replace storage selection.
> [!NOTE]
> Related: use [docs standards](README.md#2-documentation-standards) when adding
> new recipes so headings, callouts, and links stay consistent.
<br>
# 2. First-Time Setup
<!-- ======================================================== -->
## Install The Package
<!-- ======================================================== -->
Use this recipe from the Kneiff repository root.
1. Create or activate a Python environment:
```bash
python -m venv .venv
source .venv/bin/activate
.venv/bin/python -m pip install --upgrade pip
```
2. Install the package for runtime use:
```bash
.venv/bin/python -m pip install -e "."
```
3. Install the maintainer tools when you plan to edit the project:
```bash
.venv/bin/python -m pip install -e "." --group dev
```
4. If you use `uv`, sync the locked environment:
```bash
uv sync --locked --all-extras
```
> [!NOTE]
> Related: use [dependency surfaces](References.md#dependency-surfaces) for the
> difference between runtime dependencies and dependency groups.
<br>
<!-- ======================================================== -->
## Run The First Command
<!-- ======================================================== -->
Run the CLI after installation:
```bash
knf --help
```
Check the top-level command groups:
```bash
knf dataset --help
knf train --help
knf img --help
knf comfy --help
```
> [!NOTE]
> Related: use [public interfaces](References.md#public-interfaces) for the
> commands and import paths users can rely on.
<br>
<!-- ======================================================== -->
## 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:
```bash
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`:
```bash
cat > .env <<'EOF'
BASE_URL=http://localhost:1234/v1
OPENAI_API_KEY=not-needed
EOF
```
> [!CAUTION]
> Keep secrets and machine-local project roots out of committed files.
<br>
## 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:
```text
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/
```
```bash
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.
```yaml
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:
```bash
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:
```bash
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:
```bash
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:
```bash
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:
```bash
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.
<br>
# 3. Dataset Workflows
<!-- ======================================================== -->
## Sync A Manifest Workbook
<!-- ======================================================== -->
Refresh only `MANIFEST.knf.xlsx` and generated `MANIFEST.yaml` from `SOURCE/`:
```bash
knf dataset sync path/to/project/configs/example.knf.yaml --manifest-only
```
With storage selected, use the config selector instead:
```bash
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:
```bash
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.
> [!NOTE]
> Related: use [manifest-to-export model](Explanations.md#manifest-to-export-model)
> for the ownership boundary between source images, workbook rows, and exports.
<br>
<!-- ======================================================== -->
## Sync A Training Dataset
<!-- ======================================================== -->
Use a `configs/*.knf.yaml` file to map source folders to export subsets:
```yaml
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:
```bash
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:
```bash
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:
```bash
knf dataset readme path/to/project/configs/example.knf.yaml
```
Regenerate only that non-mirrored grid from the existing export directory:
```bash
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`](https://github.com/bghira/SimpleTuner/blob/main/documentation/DATALOADER.md#minimum_image_size),
[`maximum_image_size` and `target_downsample_size`](https://github.com/bghira/SimpleTuner/blob/main/documentation/DATALOADER.md#maximum_image_size-and-target_downsample_size),
and
[option](https://github.com/bghira/SimpleTuner/blob/main/documentation/OPTIONS.md)
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:
```bash
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:
```bash
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:
```bash
knf dataset sync path/to/project/configs/example.knf.yaml --rebuild
knf dataset sync path/to/project/configs/example.knf.yaml --rebuild --yes
```
> [!WARNING]
> `--rebuild` deletes existing contents under the config-derived export root.
> Review `HF/<id>/` before confirming a destructive rebuild.
<br>
<!-- ======================================================== -->
## Configure Caption Outputs
<!-- ======================================================== -->
Use `caption_outputs` for global sidecar defaults and
`caption_outputs_overrides` for per-subset changes:
```yaml
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.
> [!WARNING]
> Rows marked `SFW` reject explicit or NSFW labels, explicit anatomy, penis
> state and appearance, sexual actions, sexual fluids, and the exact tags
> `anus`, `balls`, and `genitals`.
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.
> [!IMPORTANT]
> `caption_outputs` no longer accepts per-subset mappings. Put subset-specific
> changes under `caption_outputs_overrides`.
<br>
# 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:
```bash
knf train runs example
knf train runs /abs/path/to/project/configs/example.knf.yaml
```
Prepare the generated SimpleTuner JSON files without launching:
```bash
knf train prepare example
knf train prepare alpha beta --testrun
knf train prepare /abs/path/to/project/configs/example.knf.yaml
```
> [!IMPORTANT]
> Run `knf dataset sync CONFIG` before preparing training artifacts. `knf train
> prepare` requires a populated `HF/<config-id>/` export with files in every
> enabled `training.simpletuner.subsets` entry, 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:
```yaml
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`:
```bash
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.
```yaml
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.
```yaml
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.
> [!NOTE]
> Related: use [LoRA workflow model](Explanations.md#lora-workflow-model) for
> how Kneiff translates one dataset config into SimpleTuner artifacts.
<br>
<!-- ======================================================== -->
## Launch SimpleTuner Training
<!-- ======================================================== -->
Launch SimpleTuner from the generated artifacts:
```bash
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`:
```dotenv
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:
```bash
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:
```bash
knf train start example --testrun --cuda-device 1
```
Resume a prepared or incomplete run without regenerating artifacts:
```bash
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
```
> [!IMPORTANT]
> `--resume` launches existing generated JSON files from the selected run
> workspace. It does not regenerate artifacts from the current YAML config.
> The workspace-local `dataset/` copy must still exist and contain files for
> every active image backend. If it is missing or stale, run
> `knf dataset sync CONFIG` and prepare a new run.
> Pass a run number to skip the interactive prompt. Bare `--resume` opens an
> interactive picker for `not_started` and `incomplete` runs.
> Running `knf train start` without 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:
```bash
knf train start path/to/project/configs/example.knf.yaml --cuda-device 1 --fallback-cuda-device 0
```
<br>
<!-- ======================================================== -->
## Showcase Training Checkpoints
<!-- ======================================================== -->
Set `COMFY_MODELS_DIR` to the ComfyUI models root. Its `models/loras`
directory must be writable:
```bash
COMFY_MODELS_DIR="/path/to/comfyui-models"
```
Open the shared run-first picker for numeric checkpoint files from direct
training-run `_simpletuner-output` trees:
```bash
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:
```bash
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.
> [!IMPORTANT]
> `-t` requires an interactive terminal and cannot be combined with `--lora`.
> `COMFY_MODELS_DIR` must describe the filesystem used by the running ComfyUI
> server.
<br>
<!-- ======================================================== -->
## Promote A Training Checkpoint
<!-- ======================================================== -->
Install one reviewed numeric checkpoint as a release copy below the configured
ComfyUI LoRA library:
```bash
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:
```text
<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.
<br>
# 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`:
```bash
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:
```yaml
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:
```bash
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`.
> [!IMPORTANT]
> Kneiff sends run-relative output paths to ComfyUI and uploads
> `run.knf.yaml` through the same server-managed output mechanism used by the
> showcase grid. No client-side ComfyUI output path is required. Set optional
> `COMFY_OUTPUT_DIR` or pass `--output-dir` only to keep an additional local
> mirror. Any Flux cleanup also requires `qwen_3_8b_fp8mixed.safetensors` below
> ComfyUI's text encoders and `full_encoder_small_decoder.safetensors` below
> 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`.
> [!WARNING]
> LM Studio and ComfyUI may allocate GPU memory concurrently. An OOM can come
> from either server; the command prints both URLs before generation starts.
<br>
<!-- ======================================================== -->
## Convert PNG Files To JPEG
<!-- ======================================================== -->
Convert every PNG below a directory into an output subdirectory:
```bash
knf img png2jpg ./images --out-subdir jpg --quality 95
```
Preview without writing files:
```bash
knf img png2jpg ./images --dry-run
```
<br>
<!-- ======================================================== -->
## Prepare Image Sets
<!-- ======================================================== -->
Concatenate images horizontally:
```bash
knf img concat ./a.png ./b.png --output contact-sheet.png --width 2000
```
Rename files with an enumerated random suffix:
```bash
knf img rename ./images/*.png --base-name sample --mode enum --start 1
```
Upscale one file or a directory:
```bash
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.
> [!WARNING]
> Upscaling may download model weights and can use significant GPU memory.
<br>
<!-- ======================================================== -->
## Tag And Caption Images
<!-- ======================================================== -->
Print e621-style tags from RedRocket/JTP-3:
> [!IMPORTANT]
> The current RedRocket/JTP-3 `main` snapshot requires the Python package
> `pyvips` and native `libvips`. Install Python dependencies with `uv sync` or
> `.venv/bin/python -m pip install -e .`. On Fedora WSL, install the native
> package with `sudo dnf install vips`. Current `main` uses calibrated upstream
> tag selection; `--threshold` is only for legacy pinned revisions.
```bash
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:
```bash
knf img tag ./images --recursive --txt
```
Use legacy comma-separated tag text when another workflow expects it:
```bash
knf img tag ./images --recursive --txt --comma
```
> [!NOTE]
> `--csv-stdout` is 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:
```bash
knf img caption ./image.png --server --model-name local-model
```
Caption a directory and write sidecars:
```bash
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:
```bash
knf img caption ./images --blip --model-name Qwen/Qwen2-VL-2B-Instruct
```
Generate a two-pass image prompt through LM Studio:
```bash
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:
```bash
knf llm prompt "front-view portrait, smiling" --text
```
The explicit review format is also available when scripts should spell out the
human output mode:
```bash
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:
```bash
knf llm prompt "front-view portrait, smiling" --no-export
```
Force known fields with repeated `--field FIELD=VALUE` options:
```bash
knf llm prompt "resting against a tree" \
--field character=Character_Token \
--field view=rear_view \
--field pose_body=standing,leaning
```
<br>
# 6. Maintainer Checks
<!-- ======================================================== -->
## Sync Dependencies
<!-- ======================================================== -->
Use `just sync` to install the full maintainer environment from `uv.lock`:
```bash
just sync
```
Use plain `pip` when you only need the package and do not want `uv`:
```bash
.venv/bin/python -m pip install -e "."
```
> [!NOTE]
> Related: use [configuration model](Explanations.md#configuration-model)
> for why runtime installs and maintainer installs are documented separately.
<br>
<!-- ======================================================== -->
## Run Tests
<!-- ======================================================== -->
Run the focused CLI smoke tests:
```bash
.venv/bin/pytest tests/test_cli_smoke.py
```
Run the usual quality tools before finishing a Python code change:
```bash
.venv/bin/ruff format .
.venv/bin/ruff check .
.venv/bin/pyright
.venv/bin/pytest
```
> [!NOTE]
> Related: use [Development: verification](Development.md#verification) for
> the maintainer checklist before a commit.
<br>
# 7. Troubleshooting
<!-- ======================================================== -->
## Environment Problems
<!-- ======================================================== -->
Check the active Python and import location first:
```bash
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:
```bash
.venv/bin/python -m pip install -e "."
```
For image captioning, confirm the local `.env` contains `BASE_URL` or
`OPENAI_BASE_URL`.
> [!NOTE]
> Related: use [failure model](Explanations.md#failure-model) for the normal
> order of checks when a command behaves differently across machines.
<br>
<!-- ======================================================== -->
## Command Problems
<!-- ======================================================== -->
When a `just` recipe fails:
1. Run `just --list`.
2. Run the underlying command manually.
3. Check whether the virtual environment is active.
4. Check whether the command exists in `.venv/bin`.
```bash
just --list
ls .venv/bin
```
> [!NOTE]
> Related: use [command reference](References.md#command-reference) for the
> expected commands and their owners.
<br>
<!-- ======================================================== -->
## Manifest And Config Problems
<!-- ======================================================== -->
When dataset sync fails:
1. Confirm the config file is named `configs/<dataset-id>.knf.yaml`.
2. Confirm the manifest uses the canonical `Relative_path` column.
3. Confirm `mappings` names source folders relative to `SOURCE/`.
4. Confirm `caption_outputs_overrides` names only configured subsets, plus
`sfw` when `export_sfw_subset: true`.
5. Confirm YAML keys are unique. Duplicate keys are rejected, including nested
keys such as `training.simpletuner.trainer.caption_dropout_probability`.
6. Run sync in `--dry-run` mode.
```bash
knf dataset sync path/to/project/configs/example.knf.yaml --dry-run
```
> [!NOTE]
> Related: use [configuration files](References.md#configuration-files) for the
> exact file owners and [caption sidecar model](Explanations.md#caption-sidecar-model)
> for output behavior.
|