Soul Cinema: Training an Identity Model for Exact Lookalikes
Text prompts describe a face approximately; a trained Soul identity reproduces it exactly, shot after shot, session after session.
Why a face needs training, not just a prompt
Every image and video model can generate "a woman in her thirties, dark hair, sharp jawline" from a text prompt. What none of them can do reliably from text alone is generate the SAME woman, twice, in two different scenes, with the same face down to the pore. Text prompts describe categories. They do not encode identity. Run the same detailed description through a generation model on Monday and again on Tuesday and you get two different faces that both technically match the words.
For a one-off image, that's a non-issue. For a film -- a piece with a recurring character who has to look like themselves across dozens of independently-generated shots, spread across multiple sessions, sometimes weeks apart -- it is the whole problem. You cannot direct continuity into a prompt. You have to train it.
What a Soul identity model actually is
Higgsfield's Soul system solves this by training a small personalized model on real photographs of one specific face. Once trained, that model produces a reference id -- an identity you can attach to future generation calls. Instead of re-describing the face every time and hoping the model interprets your adjectives the same way twice, you point the generation call at the trained identity and it reproduces that exact face, at whatever pose and expression the prompt asks for.
This is the mechanism underneath everything else in this track. Continuity engineering, compositing two subjects into one frame, and directing twins all assume you have a face the system actually knows -- not one it's re-guessing from adjectives on every single call.
Building a training set that actually generalizes
The quality of the trained identity is a direct function of the quality of the reference photos, and most people badly underestimate how much variety a good training set actually needs.
A weak set is easy to assemble by accident: photos from the same phone, same room, same slight smile, same three-quarter angle, taken in the same ten minutes. The model trained on it nails that exact look and falls apart the moment a shot calls for a serious expression, a profile view, or different lighting -- because it has never seen the face do anything else.
A genuinely good set has real range. Train on somewhere between 5 and 20 real photos, and make sure they cover three axes:
- Angle -- a front-neutral shot, a profile shot, and something in between (3/4).
- Expression -- neutral, a couple of more intense or serious expressions, and a few genuine smiles. Not one expression repeated five times.
- Lighting -- studio light, indoor ambient light, and outdoor daylight, ideally across different sessions rather than one single photoshoot.
The goal isn't to feed the model a portfolio -- it's to give it enough examples of the same underlying structure (bone structure, proportions, skin) under different conditions that it learns the structure itself, not one specific photo's lighting and angle. A model that has only ever seen one lighting condition has learned that lighting as part of the identity, and it will fight you every time a scene calls for something else.
The training flow: upload, train, poll, generate
The mechanics are a fixed, ordered sequence, and skipping or reordering a step breaks the pipeline.
Upload each reference photo individually. Every image is its own upload call, and every upload returns its own id. You're not sending one batch file -- you're collecting a list of ids, one per photo.
Start training, referencing every uploaded id. One training job call, passed the full list of ids collected above. This kicks off the actual model training.
Poll until training completes. This is the step people forget. Training a Soul identity is not instant -- it runs on the order of ten minutes, not seconds. Your pipeline has to check the training job's status in a loop and wait for it to report ready before doing anything else. Firing a generation call against a training job that hasn't finished yet either errors, or worse, silently generates against an identity that isn't fully formed.
Generate with the identity attached. Once training reports ready, you call an identity-conditioned generation model with your prompt AND the trained identity's reference id. The model now has both what you're asking for and who it has to look like.
The gotcha nobody warns you about
This is the failure mode that costs the most debugging time, because it does not announce itself as an error.
An identity trained through Soul comes back tagged with a reference type -- it was trained AS a specific variant, meant to pair with one specific matching generation model. If you call a different generation model with that same reference id, one that expects a different reference type, the call does not fail loudly. It runs, it returns an image, and the image is wrong: a mismatched face, a generic face, sometimes a face that's almost-but-not-quite right in a way that's easy to miss on a quick glance and expensive to catch three shots into a sequence.
The rule is simple and non-negotiable: always pair a trained identity with the generation model it was trained for. Before wiring a new step into a pipeline, verify the reference type and the target model actually match. Never assume compatibility because both are "image generation models" -- the API will not stop you from calling the wrong one.
Cost economics: cheap enough to gamble on
Once an identity is trained, generating individual stills from it is cheap -- identity-conditioned still frames typically cost a small fraction of a credit each. That changes how you should work. Because training is the expensive, slow, one-time step, and generation is the cheap, fast, repeatable step, the right workflow is to batch-generate many candidate stills from a single trained identity and pick the best one, rather than agonizing over getting one generation exactly right on the first try. Generate ten variations of an expression or a pose and choose the winner. The training cost is already sunk; the generation cost of exploring options is close to free.
Build it: the correct training-and-generation call sequence
You are going to fix a pipeline that has the right pieces but the wrong order -- no poll loop waiting for training to finish, and no check that the generation model actually matches the trained identity's reference type before firing the call.