Skip to content

Repository files navigation

LoRA Cast

Put the people you trained identity LoRAs for into a picture you already have —
one face at a time, so nobody's face bleeds onto someone else.

Website · Try the interface · Install · Troubleshooting

MIT licence Python 3.10+ Runs locally No account needed

Everything runs on your own computer, with the models you already have. Pictures and LoRAs never leave it. There is no account, no upload and no telemetry.


Contents


The problem this solves

A face LoRA applies to the whole image. Load two people's LoRAs into one render and their faces blend, or everyone ends up wearing the same face. Masking and inpainting help, but the LoRA is still loaded for the whole picture.

LoRA Cast never renders two identities together:

  1. You open a picture, made with any tool.
  2. LoRA Cast proposes a box for each face, and you say who each one is.
  3. Each face is cropped with room around it and redrawn on its own — an image-to-image render with exactly one LoRA — then blended back.

Because every face is its own render with one LoRA, identities cannot bleed. Two LoRAs that share a trigger word can even appear in the same picture.

Want to feel it before installing anything? The interface demo is the real interface, with a sample photo and the boxes the detector actually found in it.

How it works

For each face you have assigned, in turn:

  1. The box becomes a head box. The box runs from the brow line to the chin. LoRA Cast grows it outwards into a full head box, so hair and jaw are included rather than cut through.
  2. A crop is taken with context around it, 1.6× the head box, so the model can see the neck, shoulders and background it has to match.
  3. Small faces are enlarged first. If the head is much smaller than 400 px the crop is scaled up, up to 4×, because a face redrawn in a small area reads to the model as a blurry thumbnail. Set an upscale model for that enlargement to be sharp rather than merely bigger.
  4. The crop is letterboxed, never squashed, to the square the engine wants, with edge pixels replicated into the bars.
  5. One render, one LoRA. Image-to-image at your chosen face strength, with that person's LoRA at their weight, their trigger word and their description of hair and look.
  6. It is blended back through a superellipse mask, feathered at the edge and biased outwards over the hair, with colours matched to the original in Lab space, high and low frequencies recombined so skin texture survives, and film grain matched to the surrounding picture.
  7. Only the crop is resampled. The rest of your picture is untouched, pixel for pixel.

Then the next face starts from that result. Nothing about person A is loaded while person B is drawn.

What you need

Python 3.10 or newer Already on most machines. The installer checks and tells you if not.
ComfyUI or Draw Things ComfyUI on Windows, Linux and macOS. Draw Things on macOS only, with its command line tool: brew install draw-things-cli.
A base model LoRA Cast was tuned on Krea 2. Other model families work through your own workflow file and are untested.
Identity LoRAs One per person. LoRA Cast never trains anything — it uses what you already have.

An upscale model is optional, and only matters for faces that start out small.

Install it

One line on macOS or Linux. It fetches LoRA Cast, sets it up and opens it:

curl -fsSL https://raw.githubusercontent.com/Stigmavlc/lora-cast/main/install.sh | bash

It installs into ~/lora-cast. Set LORACAST_DIR to put it somewhere else. Add --upscaler at the end to install PyTorch for sharper small faces.

By hand, on any platform including Windows:

git clone https://github.com/Stigmavlc/lora-cast.git
cd lora-cast
python3 setup.py          # add --upscaler for sharper small faces (installs PyTorch)

Setup makes a virtual environment, installs a handful of dependencies, and downloads the face detector — about 350 KB, from a pinned URL, checksum-verified.

First run

Start it:

  • macOS — double-click Launch LoRA Cast.command
  • Windows — double-click launch-lora-cast.bat
  • Linux — run ./launch-lora-cast.sh

Setup creates the right launcher for your platform. It opens at http://127.0.0.1:8420 and walks you through three steps: connect an engine, add the people you trained LoRAs for, open a picture.

Windows, macOS and Linux

LoRA Cast checks which platform it is running on and adjusts:

macOS Windows Linux
ComfyUI yes yes yes
Draw Things yes not offered — the tab is hidden not offered — the tab is hidden
Choosing a folder or file a native chooser opens you are asked for the path you are asked for the path
Launcher Launch LoRA Cast.command launch-lora-cast.bat launch-lora-cast.sh
One-line installer yes clone and run setup.py yes

Draw Things is a macOS application, so on Windows and Linux its tab is hidden entirely rather than being offered and then failing. The native folder chooser is macOS-only too; everywhere else the same buttons ask you to paste a path, which works the same way.

Paths are never assumed. The Draw Things models folder is found from the app's own location or DRAWTHINGS_MODELS_DIR, and ComfyUI is reached over its HTTP API at whatever address you give it, so it does not matter where it is installed — or whether it is on this machine at all.

Connecting an engine

Open Settings. Whichever engine you connect becomes the one in use. You can disconnect and swap at any time, and each person remembers which engine their LoRA belongs to.

ComfyUI

Start ComfyUI as you normally do, then press Connect. LoRA Cast reads the models ComfyUI already has and pre-selects the Krea 2 files if they are there: a diffusion model, a text encoder and a VAE. If ComfyUI runs on another address or port, change it before connecting.

With ComfyUI you can also import a .safetensors LoRA from anywhere on disk; it is copied into ComfyUI's loras/lora-cast/ folder.

Draw Things

Install the command line tool with brew install draw-things-cli, then press Connect. LoRA Cast finds it, reads your models folder and lists the base models you have downloaded. Press Check again after installing anything new. See the trap below.

Adding people

Open People and add one person per LoRA.

Field What it is for
LoRA The file itself. With ComfyUI you can import one from anywhere; with Draw Things, import it in the app first.
Name What appears on the face boxes and in the dropdowns.
Trigger word The word their LoRA was trained with. Untick Add it to the prompt if the LoRA does not use one.
Hair and look The whole head is redrawn, so anything you leave out gets invented. Describe hair, facial hair, glasses, earrings.
LoRA weight 0.1 to 2.5, default 1.0, under More. Some LoRAs need well above 1.0 before they show up properly.
Hair bias How far the blend mask reaches out over the hair, default 1.12, under More.
Colour The colour of that person's box and label.

Then press Save and test. The test renders one small picture twice with the same seed, with and without the LoRA, and compares them. Identical renders mean the LoRA did nothing, and that person cannot be assigned to a face until it passes. It takes a minute or two, because it is two real renders.

Using it

Open a picture and LoRA Cast proposes a box for each face.

  • Drag on the picture to add a box.
  • Drag a box to move it, or its corners to resize it.
  • Drag the dot above a box to rotate it for a tilted head.
  • Click the middle of a box to say who it is, or to delete it.
  • Select a box and press Backspace to delete it.

The box should run from the brow line to the chin. LoRA Cast grows it into a head box itself, so a box drawn much larger fights that.

Say who each face is, then press Apply. Applying again always starts from the original picture, never from a previous result, so you can try seeds and strengths without degrading anything. When it finishes you can Compare before and after and Save picture.

Every setting

Per picture

Setting Range What it does
Face strength 0.30–0.95, default 0.50 How much of the original face is thrown away before redrawing. Around 0.40 the expression stays natural; by 0.70 the likeness is strongest but faces start to pull into a grimace; above about 0.85 the composite breaks down. It cannot exceed 1.0, which would mean discarding the face entirely.
Seed 0 to 4294967295 The same picture, settings and seed give the same result. Change it for a different take.

Per face

Setting What it does
Who this is Whose LoRA is used. Only people whose LoRA passed its test appear.
Expression Optional. The whole head is redrawn, so without it a face comes back with the expression its LoRA was trained on.
Angle Set by rotating the box. The face is rendered upright and rotated back.

Global

Setting What it does
Engine ComfyUI or Draw Things. Only one is in use at a time.
Base model Which checkpoint faces are rendered with. Krea 2 is what LoRA Cast was tuned on.
Sharper small faces An optional upscale model, used when a face has to be enlarged before rendering. Needs setup run with --upscaler.

The Draw Things trap

⚠️ Draw Things only applies a LoRA that was imported in the Draw Things app, where it becomes a .ckpt. A raw .safetensors file renders happily and applies nothing at all, with no warning at any point — you get a plausible picture that simply is not the person.

LoRA Cast refuses those out loud, and its LoRA check proves the rest really work. If a person shows Did nothing, import their LoRA in the Draw Things app, choosing the right base model by hand, and point LoRA Cast at the .ckpt it produces.

Other models and your own workflow

LoRA Cast was tuned on Krea 2, but ComfyUI can run anything through a workflow file of your own.

  1. Build the graph you want in ComfyUI and export it with Export (API).
  2. Put these placeholders where those values belong: {{image}}, {{prompt}}, {{lora}}, {{lora_weight}}, {{strength}}, {{seed}}. {{steps}} is optional.
  3. Save it in data/workflows/ and pick it in Settings.

Everything outside the render — the head box, the enlargement, the mask, the colour matching, the grain — works the same whatever model you use.

Where your files live

Everything LoRA Cast writes stays inside the folder you installed it into:

Path What it holds
data/people.json The people you added, and their test results.
data/settings.json Your engine, model and interface settings.
data/pictures/ Pictures you opened and results you made.
data/workflows/ Your own ComfyUI workflow files.
models/ The face detector, downloaded by setup.

Set LORACAST_DATA to keep data/ somewhere else. Nothing is written outside these.

Command line

The interface is the intended way to use LoRA Cast, but the same pipeline is available directly, which is useful for scripting and for checking something in isolation:

python -m loracast setup                       # download the detector, make the data folder
python -m loracast detect picture.png          # print the proposed faces as JSON
python -m loracast check <person-id>           # prove that person's LoRA changes the render
python -m loracast apply picture.png \
    --face 294,212,427,398,nadia,-11 \
    --face 603,183,722,349,mara \
    --expression 0:"a slight smile" \
    --strength 0.5 --seed 0 --out result.png

--face takes X1,Y1,X2,Y2,PERSON[,ANGLE] and is repeated once per face. --expression takes INDEX:TEXT, counting faces from 0.

Troubleshooting

What you see What to do
"Can't reach ComfyUI…" Start ComfyUI, then press Connect. If it runs on another port, change the address.
"draw-things-cli isn't installed" brew install draw-things-cli, then press Check again.
No Draw Things tab You are not on macOS. Draw Things is a macOS app; use ComfyUI.
A person's LoRA says Did nothing The file isn't in a format the engine applies. With Draw Things, import it in the app so it becomes a .ckpt.
A person's LoRA says File missing It was moved or renamed. Choose it again in People.
The face dropdown is empty It lists people, not LoRA files. Add a person first — the button is in the face list.
Apply is greyed out Either no face has been assigned yet, or a LoRA check is still running. The button says which.
Faces come back soft Small faces are enlarged before they are redrawn. Set an upscale model under Sharper small faces, and run setup with --upscaler.
A seam across the forehead The box should run from the brow line to the chin. LoRA Cast grows it into a head box itself; a box drawn much larger fights that.
Faces look airbrushed Try a bigger picture. A face redrawn in a small area reads to the model as a beauty close-up.
The likeness is weak Raise that person's LoRA weight before raising face strength. Many LoRAs need more than 1.0.
The expression looks forced Lower face strength towards 0.40, or set an expression for that face.
A render takes minutes That is the engine, not LoRA Cast. Each face is its own render, and a LoRA check is two.

Privacy

LoRA Cast is a small local server bound to 127.0.0.1, talking to the rendering engine already on your machine. It checks the Host and Origin of every request, runs one job at a time, and never opens a connection to anywhere else. The only thing it ever downloads is the face detector, once, during setup, from a pinned URL with a checksum.

Your pictures, your LoRAs and your results stay on your disk. This is also why the website cannot render for you: the graphics card doing the work has to be yours.

Responsible use

Only use LoRAs of people who have agreed to it, and never of minors. Do not use LoRA Cast to impersonate anyone, to deceive, or to make intimate images of someone without their consent. Follow the licences of the models and LoRAs you use.

Development

python3 setup.py                                  # environment and dependencies
.venv/bin/python -m pytest                        # the test suite
.venv/bin/python -m loracast.server --no-browser  # run it without opening a browser
python3 docs/demo/build.py                        # rebuild the website demo after changing the interface

The code is deliberately small and dependency-light: OpenCV and NumPy do the image work, the server is the standard library, and the interface is one HTML file with no build step and no framework.

Module What it does
loracast/detect.py Proposes face boxes with YuNet.
loracast/faces.py The head box, the crop, the mask and the blend.
loracast/harness.py Letterboxing, and putting a render back where it came from.
loracast/upscale.py Optional enlargement of small faces.
loracast/people.py The people store and its validation.
loracast/lora_check.py Proving a LoRA actually does something.
loracast/engines/ The engine contract, and the ComfyUI and Draw Things adapters.
loracast/server.py The local server and its JSON API.
web/index.html The whole interface.

Issues and pull requests are welcome.

Credits and licence

LoRA Cast is MIT-licensed — see LICENSE.

  • Face detection: YuNet from OpenCV Zoo, MIT licence, downloaded and checksum-verified by setup.
  • Type: Instrument Sans, SIL Open Font License, bundled in web/fonts/.
  • Models and LoRAs keep their own licences; none are bundled.

About

Put the people you trained identity LoRAs for into any picture — one face at a time, on your own machine. ComfyUI or Draw Things.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages