Train a character/identity LoRA locally on FLUX.1-dev
Train a Character LoRA (local, Flux.1-dev)

Train a character/identity LoRA locally on FLUX.1-dev via the comfyui-mcp train_* tools (GPU Docker + ostris ai-toolkit). Use when the user wants to train a LoRA of a person/character from their photos on the local GPU.
--- name: train-character-lora description: Train a character/identity LoRA locally on FLUX.1-dev via the comfyui-mcp train_* tools (GPU Docker + ostris ai-toolkit). Use when the user wants to train a LoRA of a person/character from their photos on the local GPU. Covers dataset prep, launch, monitoring, and using the result in ComfyUI. For WAN/Z-Image training via the ai-toolkit UI see ai-toolkit-trainer. globs: - "**/*.json" --- # Train a Character LoRA (local, Flux.1-dev) ## Overview The trainer runs ostris ai-toolkit's `run.py` inside a headless GPU Docker container, driven through the three `train_*` MCP tools. You (the LLM) are the UI. Each takes an `action`: `train_prepare_dataset` owns the datasets, `train_start` owns the jobs, and `train_doctor` owns the trainer itself. You generate the dataset, launch the job, watch progress, and the finished LoRA lands in ComfyUI `models/loras/` and the LoRA catalog without further steps.
Overview
The trainer runs ostris ai-toolkit's run.py inside a headless GPU Docker container, driven through the three train_* MCP tools. You (the LLM) are the UI. Each takes an action: train_prepare_dataset owns the datasets, train_start owns the jobs, and train_doctor owns the trainer itself. You generate the dataset, launch the job, watch progress, and the finished LoRA lands in ComfyUI models/loras/ and the LoRA catalog without further steps.
Manual install (npx, ZIP)
npx skills add artokun/comfyui-mcp --skill train-character-lora -g -a claude-codemkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/artokun/comfyui-mcp/tar.gz/1d5b12b1b499 \
| tar -xz -C ~/.claude/skills --strip-components=3 comfyui-mcp-1d5b12b1b499/plugin/skills/train-character-loraNew-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null; Invoke-WebRequest "https://m.agentalley.io/zip/00207f9aa3d19bfa6057/train-character-lora.zip" -OutFile "$env:TEMP\train-character-lora.zip"; Expand-Archive "$env:TEMP\train-character-lora.zip" -DestinationPath "$HOME\.claude\skills" -ForceConnects with Agent Alley MCP · agentalley.io/mcp
Files included
SKILL.md5.1 KB
Read the files here
artokun/
Show the full text95 lines
Train a Character LoRA (local, Flux.1-dev)
Overview
The trainer runs ostris ai-toolkit's run.py inside a headless GPU Docker container,
driven through the three train_* MCP tools. You (the LLM) are the UI. Each takes
an action: train_prepare_dataset owns the datasets, train_start owns the jobs, and
train_doctor owns the trainer itself. You generate the dataset, launch the job, watch
progress, and the finished LoRA lands in ComfyUI models/loras/ and the LoRA catalog
without further steps.
- Base model: FLUX.1-dev (the best proven character consistency; needs ~24GB VRAM with quantization, RTX 4090 class).
- Phase-1 scope: character LoRAs only. Style/slider/edit and other bases come later.
The flow (tool sequence)
train_doctor {action:"doctor"}. Preflight once per session. Checks docker daemon,--gpus allGPU passthrough, trainer image, HF_TOKEN. Ifimage:false, runtrain_doctor {action:"build_image"}(one-time, several minutes, since it builds CUDA plus torch plus ai-toolkit). IfhfTokenSet:false, warn the user: the first run downloads FLUX.1-dev (gated HF repo) and needsHF_TOKENin the MCP server env.train_prepare_dataset {action:"prepare"}. Stage the images. See "Dataset" below.train_start {action:"start"}. Launch. Returns a job id at once; training runs detached.train_start {action:"status", id}. Poll progress (progress.step/totalSteps/loss, recentsamples,logtail). Poll on a slow cadence (every few minutes). A 2000-step run is roughly an hour on a 4090. Don't block on it.- Done.
status:"completed"means the.safetensorswas copied tomodels/loras/<name>.safetensorsand upserted into the LoRA catalog (resulthas the paths and catalog id). Verify by loading it in a Flux workflow (LoraLoaderModelOnly, strength 1.0) with the trigger word in the prompt.
Dataset guidance
Call train_prepare_dataset {action:"prepare"} with name, items: [{path, caption?}, ...]
and a defaultCaption.
- 10 to 30 varied images of the subject: different angles, expressions, lighting, backgrounds, distances (close-up, half-body, full-body). Variety beats count.
- Trigger word: pick something rare and stable (e.g.
ohwx,zxc_person), NOT a real word. Use it asdefaultCaptionand pass it astriggertotrain_start. - Captions: describe what changes between images (pose, setting, clothing,
expression); the model learns the constant identity from the images themselves. Start
each caption with the trigger word, e.g.
ohwx person sitting in a cafe, laughing, natural light. Keep them short and factual. When in doubt, the trigger word alone (defaultCaption) is a workable baseline. - Images are copied and renamed
img_00001.<ext>etc. Source files are never modified.
Params (sane defaults — override sparingly)
| Param | Default | When to change |
|---|---|---|
| steps | 2000 | 200 for a smoke test; 1500–3000 real runs. More ≠ better (overbake = plasticky). |
| lr | 1e-4 | 5e-5 for a tighter/subtler identity. |
| rank | 16 | 32 for very detailed characters. |
| resolution | [512,768,1024] | [512] if VRAM-constrained. |
| quantize | true | Keep true on 24GB. |
| saveEvery / sampleEvery | 250 | Lower (100) to watch early progress. |
Monitoring & judgement
train_start {action:"status"}'sprogress.samplesare host paths. Look at them. (ai-toolkit prints no saved-sample lines, so they populate at finalize from the output dir; mid-run you can look directly in the job'soutput/<name>/samples/folder.) Identity should be recognizable by ~1/3 of the run; if samples stay generic past halfway, the run will likely underfit. Cancel (train_start {action:"cancel", id}) and check captions and trigger.- Loss should trend down and stabilize (~0.1 to 0.3); wild spikes usually mean lr too high.
- Checkpoints save every
saveEverysteps under the job'soutput/dir, so a cancelled run isn't a total loss.
Failure modes
no_docker/no_imagefromtrain_start {action:"start"}: runtrain_doctor {action:"doctor"}, follow its hints.- OOM / CUDA errors in the log tail: drop
resolutionto[512], keepquantize:true, batch stays 1. handoff failedin job error: training itself finished; the LoRA is still under the job'soutput/<name>/dir. Copy it intomodels/loras/manually and upsert the catalog.- First run is slow before step 1. FLUX.1-dev download (~24GB) plus latent caching. As long as the log tail moves, it's fine. The HF cache persists across runs.
Sources
- Official: none found.
- Empirical: sampler values, wiring, and prompt notes from working graphs in
packs/and observed renders; not a vendor prompting guide.
| 1 | |
| 2 | name train-character-lora |
| 3 | description Train a character/identity LoRA locally on FLUX.1-dev via the comfyui-mcp train_* tools (GPU Docker + ostris ai-toolkit). Use when the user wants to train a LoRA of a person/character from their photos on the local GPU. Covers dataset prep, launch, monitoring, and using the result in ComfyUI. For WAN/Z-Image training via the ai-toolkit UI see ai-toolkit-trainer. |
| 4 | globs |
| 5 | - "**/*.json" |
| 6 | |
| 7 | |
| 8 | # Train a Character LoRA (local, Flux.1-dev) |
| 9 | |
| 10 | ## Overview |
| 11 | |
| 12 | The trainer runs ostris ai-toolkit's `run.py` inside a headless GPU Docker container, |
| 13 | driven through the three `train_*` MCP tools. You (the LLM) are the UI. Each takes |
| 14 | an `action`: `train_prepare_dataset` owns the datasets, `train_start` owns the jobs, and |
| 15 | `train_doctor` owns the trainer itself. You generate the dataset, launch the job, watch |
| 16 | progress, and the finished LoRA lands in ComfyUI `models/loras/` and the LoRA catalog |
| 17 | without further steps. |
| 18 | |
| 19 | Base model: FLUX.1-dev (the best proven character consistency; needs ~24GB VRAM with |
| 20 | quantization, RTX 4090 class). |
| 21 | Phase-1 scope: character LoRAs only. Style/slider/edit and other bases come later. |
| 22 | |
| 23 | ## The flow (tool sequence) |
| 24 | |
| 25 | `train_doctor {action:"doctor"}`. Preflight once per session. Checks docker daemon, |
| 26 | `--gpus all` GPU passthrough, trainer image, HF_TOKEN. If `image:false`, run |
| 27 | `train_doctor {action:"build_image"}` (one-time, several minutes, since it builds CUDA |
| 28 | plus torch plus ai-toolkit). If `hfTokenSet:false`, warn the user: the first run |
| 29 | downloads FLUX.1-dev (gated HF repo) and needs `HF_TOKEN` in the MCP server env. |
| 30 | `train_prepare_dataset {action:"prepare"}`. Stage the images. See "Dataset" below. |
| 31 | `train_start {action:"start"}`. Launch. Returns a job id at once; training runs |
| 32 | detached. |
| 33 | `train_start {action:"status", id}`. Poll progress (`progress.step/totalSteps/loss`, |
| 34 | recent `samples`, `log` tail). Poll on a slow cadence (every few minutes). A 2000-step |
| 35 | run is roughly an hour on a 4090. Don't block on it. |
| 36 | Done. `status:"completed"` means the `.safetensors` was copied to |
| 37 | `models/loras/<name>.safetensors` and upserted into the LoRA catalog (`result` has the |
| 38 | paths and catalog id). Verify by loading it in a Flux workflow (`LoraLoaderModelOnly`, |
| 39 | strength 1.0) with the trigger word in the prompt. |
| 40 | |
| 41 | ## Dataset guidance |
| 42 | |
| 43 | Call `train_prepare_dataset {action:"prepare"}` with `name`, `items: [{path, caption?}, ...]` |
| 44 | and a `defaultCaption`. |
| 45 | |
| 46 | 10 to 30 varied images of the subject: different angles, expressions, lighting, |
| 47 | backgrounds, distances (close-up, half-body, full-body). Variety beats count. |
| 48 | Trigger word: pick something rare and stable (e.g. `ohwx`, `zxc_person`), NOT a |
| 49 | real word. Use it as `defaultCaption` and pass it as `trigger` to `train_start`. |
| 50 | Captions: describe what changes between images (pose, setting, clothing, |
| 51 | expression); the model learns the constant identity from the images themselves. Start |
| 52 | each caption with the trigger word, e.g. `ohwx person sitting in a cafe, laughing, natural |
| 53 | light`. Keep them short and factual. When in doubt, the trigger word alone |
| 54 | (`defaultCaption`) is a workable baseline. |
| 55 | Images are copied and renamed `img_00001.<ext>` etc. Source files are never modified. |
| 56 | |
| 57 | ## Params (sane defaults — override sparingly) |
| 58 | |
| 59 | | Param | Default | When to change | |
| 60 | |-------|---------|----------------| |
| 61 | | steps | 2000 | 200 for a smoke test; 1500–3000 real runs. More ≠ better (overbake = plasticky). | |
| 62 | | lr | 1e-4 | 5e-5 for a tighter/subtler identity. | |
| 63 | | rank | 16 | 32 for very detailed characters. | |
| 64 | | resolution | [512,768,1024] | [512] if VRAM-constrained. | |
| 65 | | quantize | true | Keep true on 24GB. | |
| 66 | | saveEvery / sampleEvery | 250 | Lower (100) to watch early progress. | |
| 67 | |
| 68 | ## Monitoring & judgement |
| 69 | |
| 70 | `train_start {action:"status"}`'s `progress.samples` are host paths. Look at them. |
| 71 | (ai-toolkit prints no saved-sample lines, so they populate at finalize from the output |
| 72 | dir; mid-run you can look directly in the job's `output/<name>/samples/` folder.) |
| 73 | Identity should be recognizable by ~1/3 of the run; if samples stay generic past |
| 74 | halfway, the run will likely underfit. Cancel (`train_start {action:"cancel", id}`) and |
| 75 | check captions and trigger. |
| 76 | Loss should trend down and stabilize (~0.1 to 0.3); wild spikes usually mean lr too high. |
| 77 | Checkpoints save every `saveEvery` steps under the job's `output/` dir, so a cancelled |
| 78 | run isn't a total loss. |
| 79 | |
| 80 | ## Failure modes |
| 81 | |
| 82 | `no_docker` / `no_image` from `train_start {action:"start"}`: run |
| 83 | `train_doctor {action:"doctor"}`, follow its hints. |
| 84 | OOM / CUDA errors in the log tail: drop `resolution` to `[512]`, keep `quantize:true`, |
| 85 | batch stays 1. |
| 86 | `handoff failed` in job error: training itself finished; the LoRA is still under the |
| 87 | job's `output/<name>/` dir. Copy it into `models/loras/` manually and upsert the catalog. |
| 88 | First run is slow before step 1. FLUX.1-dev download (~24GB) plus latent caching. As |
| 89 | long as the log tail moves, it's fine. The HF cache persists across runs. |
| 90 | |
| 91 | ## Sources |
| 92 | |
| 93 | **Official:** none found. |
| 94 | **Empirical:** sampler values, wiring, and prompt notes from working graphs in `packs/` and observed renders; not a vendor prompting guide. |
| 95 |
Details
- Updated
- Sep 21, 2026
- License
- MIT
- Stars on the repo
- ★ 759
- Checked
- Source
- artokun/comfyui-mcp ↗
- Creator
- artokun · 44 listings
Similar skills
See all →
SkillMake Japanese TV-anime style videos with codeAnime cel
SkillDirect and produce a short film made entirely in codeLemo opuscar
SkillGenerate Ian-style Xiaohei illustrations for articles, posts
SkillCreating game art through Scenario MCP: spritesScenario game assets
SkillTrain custom LoRAs with ostris AI-ToolkitAI-Toolkit LoRA Trainer (WAN 2.2 & Z-Image)
SkillAnime/illustration text-to-imageANIMA 1.0 (Anima Base Ultra) Text-to-Image WorkflowsMore from artokun
SkillTrain custom LoRAs with ostris AI-ToolkitAI-Toolkit LoRA Trainer (WAN 2.2 & Z-Image)
SkillAnime/illustration text-to-imageANIMA 1.0 (Anima Base Ultra) Text-to-Image Workflows
SkillAuthoring & Publishing ComfyUI Custom Nodes
SkillTrain a custom anime LoRA on the ANIMA base modelCitron Anima LoRA Trainer
SkillDiscover Civitai models with the BUILT-IN downloadmodelCivitai + comfyui-mcp
SkillDiagnose and fix video/image color OBJECTIVELYColor Correction (measure, don't eyeball)