Vol.03 of this series started with that one sentence. General-purpose image models redraw a balloon fit as a regular fit, and wide-leg pants as straight-leg. They regress toward the average of their training data.
At first we assumed it was a prompting problem. We wrote longer, more specific, more forceful instructions. The results were the same, and of course they were. A silhouette the model has never learned will not appear, no matter how precisely you ask for it. You cannot inject knowledge through language. Knowledge only enters through training.
So in that piece we put it this way: words only summon what already exists, they do not create what is missing. What the model does not know, you have to show it. Then we ran an experiment teaching one brand's silhouettes through LoRA (Vol.05).
This article is what came next: taking that experiment to production scale. Not one brand, but every garment category we handle. The process came down to four forks in the road.
01 · The Fork
The first fork was scale. Build our own model from scratch, or put only our knowledge on top of an already powerful open model? LoRA (Low-Rank Adaptation) is the latter. You leave the base model's tens of billions of parameters untouched and attach a small adapter beside them that learns one specific thing. It is closer to slipping a thin sticky note into a book than rewriting the book. The note is light, you can make many of them, and you can peel it off at any time.
| Building a foundation model | LoRA | |
|---|---|---|
| Cost · time | Millions of dollars, months | A few GPU days |
| Data required | Hundreds of millions of images | Hundreds of pairs per category |
| Update cadence | Retraining is a project in itself | Quarterly updates are feasible |
| Benefit from base progress | None. Your model only grows if you grow it | Switch to a better open base when one lands |
| Cost of failure | The whole project | One LoRA |
The table makes it look obvious, but the deciding factor was not cost. It was cadence. Fashion trends turn over by season. For a general model to reflect a new trend, you wait for the next version, and half a year to a year goes by. Building your own foundation model changes nothing about that. Anything trained "heavily, once" cannot keep pace with the seasons. LoRA makes "lightly, often" possible. For a business that sells trends, the latter is structurally the right tool.
The limits are just as clear. LoRA cannot conjure what the base model does not know. We could take this route because our goal was not "creating a new capability" but the narrow task of "correcting the silhouette and details of clothes the model already knows how to draw." It was not that the tool was good. The task and the tool matched.
02 · The Base
We narrowed the base down to two candidates: Qwen-Image-Edit 2511 (20B) and FLUX.2 Klein 9B. Both carry the Apache 2.0 license, so the commercial constraints were identical, and that left quality as the only criterion.
We ran both with the same training data, the same recipe, and the same evaluation set. Qwen came out ahead consistently. The gap was widest in exactly the area that is fatal for apparel: reproducing fine detail such as prints, lettering, and knit texture. Given that the Qwen-Image family was designed with text rendering in mind from the start, the result made sense in hindsight.
The bake-off left us with one more thing. If you design the data and the evaluation harness to be model-neutral rather than tied to one base, reopening the competition when a better base appears costs almost nothing. Designing on the assumption that the base will change is, we think, table stakes for running training in an open-model ecosystem.
03 · Sixty-One
The next fork. Build one big LoRA that teaches "clothing in general," or split it finely by item? We chose to train 61 LoRAs, split by gender and subcategory.
The reason is simple. The silhouette a knit has to learn and the silhouette slacks have to learn are different knowledge. What matters in a knit is the texture of the stitch and how it falls along the body. What matters in pants is the rise, the leg width, and how the hem breaks over the shoes. Cram all of that into one adapter and they average each other out and dilute. You end up reproducing, inside the adapter, the exact problem you set out to fix.
This is a different axis from the brand LoRAs in Vol.03 and Vol.05. If a brand LoRA is the vertical axis that learns "this brand's sensibility," a subcategory LoRA is the horizontal axis that learns "this item's structure." The structure also helps in operation. At generation time you pick exactly one LoRA matching the requested model's gender and the garment's subcategory, and when trends shift you retrain only the LoRA for the item that changed. The "lightly, often" from the first fork is completed here.
Under each major category (outer, top, bottom), every subcategory was trained separately for men and for women. At generation time exactly one of these is selected and laid over the base model.
04 · Pairs
The training data comes from photography StyleRoom shot in-house. What matters here is not the count but the structure. We designed the data as pairs of a product shot and a worn shot, not as a heap of loose images. Only when you show the garment as it hangs alongside the same garment as it sits on a body does the model learn the relationship itself: how this piece falls on a person.
A training pair and its caption. The token at the front of the caption (example shown) is the key that binds this knowledge to a subcategory. Call the same token at generation time and the learned silhouette for that subcategory is summoned.
Each subcategory got its own trigger token in the caption. It is a name tag on the learned knowledge. Thanks to that tag we can pull in exactly "the silhouette knowledge for knit sweaters" at inference time, and the 61 LoRAs never interfere with one another.
05 · The Metal
Both training and generation ran on a VM with a single NVIDIA H100 80GB. The word "single" is the point. A 20B model in bf16 comes to roughly 56GB, and even with the LoRA adapters and working buffers on top, it fits on one 80GB card. At our scale one large GPU beats several small ones, because splitting a model across multiple GPUs is itself complexity you have to operate.
We rent the GPU from Google Cloud, for a simple reason: the training data and checkpoints already live in GCS. Calling a GPU to where the data is costs less and takes less time than moving hundreds of thousands of images to where the GPU is. We do not keep VMs around. One spins up when there is work, and deletes itself after a set period of idleness. A GPU is not a thing you own, it is time you rent.
There is one practical constraint to this approach. H100s are not always in stock in the zone you want. Some days we get one in Singapore, some days in the US central region, some days in Europe. So the VM was built from the start to "come up in the same state from a fetched script no matter which region it boots in." Chasing stock across zones is part of the operation.
For the training framework we used DiffSynth-Studio, the open-source project with official Qwen-Image support.
The key technique on the generation side is LoRA hot-swapping. The common way to use a LoRA is to fuse the adapter into the base model, but with 61 adapters that approach falls apart: 61 fused copies are 61 copies of a 20B model. Instead we keep one base model resident in GPU memory and swap in only the adapter for the relevant subcategory as each request arrives. Fusing cannot be undone; hot-swapping can change per request. That is how a single GPU ends up serving all 61 subcategories.
One thing has to be verified in this setup: when you detach the adapter, does the base model really return to what it was? We adopted the structure only after confirming that the base output after attaching and detaching an adapter was bit-for-bit identical to the original. If swapping adapters contaminated the base, the 61 would bleed into each other's results.
| GPU | NVIDIA H100 80GB × 1 (same for training and generation) |
| Cloud | Google Cloud. Call the GPU to where the data (GCS) is. Auto-deleted when idle |
| Training | DiffSynth-Studio · rank 32 · 12 epochs · checkpoint per epoch |
| Generation | Resident bf16 base (about 56GB) + LoRA hot-swap · 40 steps · 1792px tall |
| Comparison runs | Fixed seed. Only the difference between base and LoRA remains |
06 · The Recipe
The recipe itself is plain: rank 32, 12 epochs. What we put effort into was not the values but the structure. We save a checkpoint at the end of every epoch so that, once training finishes, we can choose among twelve points in time.
We do this because most LoRA training failures are overfitting. Teach too long and the model starts memorizing the training photographs themselves rather than the garment's silhouette. But "how much teaching is enough" differs by subcategory, and you cannot know before you run it. So we designed training to be reversible. Even if we only learn afterward that we passed the optimum, we can step back to the checkpoint before it.
07 · Three Traps
Everything above is design. Below is what we actually ran into. Three things gave us the most trouble while training 61 adapters.
The base model put a female model in menswear often enough to be a problem. Which makes sense: a single photo of a garment carries no information about who wears it, and the model simply leans toward whichever it saw more often in training. Instruct gender in the prompt and you still lose when the garment's appearance pulls the other way. So we split each subcategory once more by gender and trained menswear knits and womenswear knits as entirely separate LoRAs. Half of the number 61 comes from that decision.
Training photos do not contain only clothes. Framing, lighting and the mood of the background are in there too, and the LoRA learns all of it as one bundle. This is the phenomenon we described in Vol.05 as "it learns what you did not write in the caption." Left alone, a given subcategory starts emitting nothing but upper-body close-ups, because that is how the training photos were framed.
The fix is a separation principle in the captions. Anything you write in the caption becomes a variable you can control by instruction; anything you leave out gets baked into the trigger token. So the captions state not only the garment's attributes but the framing as well. Add a phrase like "worn by the person, upper body" and framing is pulled out into the caption, leaving the token to summon knowledge that is about the clothes.
The checkpoint strategy from the recipe turned out to be a requirement, not insurance. Run training all the way through and the checkpoint actually worth deploying came almost always before the final epoch. A model taken to the end starts memorizing the training photographs instead of the garment's silhouette. It is the same conclusion as Vol.05: the best fit is not when the result is best. The trouble is that you cannot know where that optimum is until you run it, which is why "save every epoch" has to be designed before training starts. A plan made after training ends is no use.
08 · Result
trained to completion
vs base (0-255 scale)
internal validation set
All 61 subcategories finished training. We measured the effect with an internal validation set, generating the base model and the LoRA-applied version side by side from the same garment and the same seed. Across 27 garments, the mean pixel difference between the two results had a median above 37 on the 0-255 scale. That is not fine-tuning. That is a different picture.
The direction of the change summarizes into three strands: silhouette (leg width, length and neckline move toward the product), texture and detail (stitch, placket and print come back), and model consistency (gender and body type stay as requested). Two scenes from validation:



Wide denim with a flat waistband. The base model turned the waist into an elastic band; the LoRA version brought the waistband and leg width back to the product.



Trap 1 and the result in one frame. The base model put menswear on a female model and flattened the detail too. A single subcategory LoRA catches both problems at once.
To be honest about it, not every item improved by the same margin. Items with a lot of texture and detail (knits, shirts) gained the most, while simple basics were already drawn well by the base model. A LoRA works in proportion to what the base does not know. Which makes the per-subcategory split useful again, because we can put extra effort only into the items that are not working.
09 · The System
Four decisions, in summary.
- LoRA, not a foundation model. The side that can keep pace with the trend cycle
- Base chosen by a like-for-like bake-off. Same license, so quality alone decided
- 61 subcategories, not one. Because silhouette is different knowledge for every item
- Pairs, not loose images. A data structure that teaches the relationship between garment and wear
The four point in one direction. We were not trying to build "a finished model." We were building a system where, whenever the trend changes, only the part that changed has to be taught again, and that system is running today. When next season's silhouette arrives, one of the 61 will be quietly replaced.
We closed Vol.03 like this: we borrow the model, but what stays on top of it is ours. Now that sentence has a number attached. Sixty-one.