Skip to content

feat(training): headless CLI for MiniMax H3 still and clip LoRAs - #40

Open
johndpope wants to merge 2 commits into
inlineresearch:mainfrom
johndpope:feat/headless-minimax-h3-lora-cli
Open

feat(training): headless CLI for MiniMax H3 still and clip LoRAs#40
johndpope wants to merge 2 commits into
inlineresearch:mainfrom
johndpope:feat/headless-minimax-h3-lora-cli

Conversation

@johndpope

Copy link
Copy Markdown

Summary

  • Add a headless training path so MiniMax H3 (and the other Trainer archs) can train from a captioned folder without starting the Studio SPA.
  • python -m inline_core.training still accepts the existing manifest.json the Trainer tab already spawns; it now also accepts --dataset / --clip-seconds / --arch and stages the dataset (including Hugging Face metadata.jsonl captions) into the same manifest shape.
  • Document the video/clip LoRA pathway in TRAINING.md and link it from the README.

This is the missing ops surface for rented GPUs / Docker: clip LoRAs that learn motion via --clip-seconds (1s ≈ 22 frames @ 24fps), same VRAM story as the site guide.

Usage

cd core
python -m inline_core.training \
  --dataset /path/to/clips \
  --arch minimax-h3 \
  --clip-seconds 1 \
  --models-dir ./models \
  --output ./models/loras/my_h3_clip.safetensors \
  --steps 500 --resolution 512

--dry-run stages and prints the manifest without loading the GPU. --resume --work-dir … continues from checkpoints. Progress remains JSON lines on stdout.

Test plan

  • uv run pytest tests/test_training_cli.py (11 passed) — staging, metadata.jsonl, hyperparams, dry-run, manifest back-compat
  • uv run ruff check on the new/edited training modules
  • Optional GPU smoke: short H3 clip run on a ≥24GB card with minimax_h3_fl2va_bf16.safetensors present

Train from a captioned folder without starting the Studio UI or writing a
manifest by hand. The same subprocess entry the Trainer tab already uses now
accepts --dataset / --clip-seconds / --arch and stages metadata.jsonl into
sidecar captions. Document the video path and cover it with unit tests.

Signed-off-by: John D. Pope <jp@bellgeorge.com>
Log train/loss, step, peak VRAM and cache status when WANDB_PROJECT (or
--wandb-project) is set. Print the run URL on stderr for Vast babysitters.

Signed-off-by: John D. Pope <jp@bellgeorge.com>
@imprsnst imprsnst added the enhancement New feature or request label Aug 10, 2026
@imprsnst
imprsnst self-requested a review August 10, 2026 05:50
@imprsnst

Copy link
Copy Markdown
Collaborator

Hi @johndpope
Thanks for this, the CLI itself is well done and the back-compat is careful: protocol.error is preserved on every failure path, the positional manifest still works so the Studio spawn is unaffected, and reworking the OOM message to drop "the node's Adjust panel" was the right call for a CLI. Nice test coverage on staging and metadata.jsonl too.

Three things before merge:

1. Rebase on main. The branch is 19 commits behind and currently conflicts. v1.2.65 and v1.2.66 landed CUDA wheel selection, a uv fix, and two trainer fixes. One conflict, in trainer.py, and both sides are wanted:

        clip_window=str(hp.get("clipWindow") or "start"),
        on_status=_cache_status,

I test-merged locally and the full suite passes at 838 once that is resolved, so it should be quick.

2. Please split the Weights & Biases work into its own PR. It is about 60 lines and it is a different thing from a headless CLI: a new outbound network dependency inside the training loop deserves its own review. Two specifics for when it comes back:

  • wandb is not declared in pyproject.toml. The try/except ImportError handles absence, but with no extra there is no supported way to install it.
  • wandb.init() does network I/O and can block. It currently runs before check_base_mappable, so on a rented box with no network or bad credentials it hangs before the cheap preflight, which is exactly the environment this targets.

Also worth reconsidering there: status="wandb requested but package missing" and status=f"wandb {url}" go through protocol.progress, which the UI shows as the current training phase. We just fixed that channel for reporting the wrong phase, so it is better kept for phases.

3. One lint failure: trainer.py:183 is 101 characters. ruff check should be clean.

With the W&B part lifted out, the rest looks good to me. Couple of users requested CLI support so this would be a great improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants