Modelli e pesi
di Diff-FIT Studio

Cosa viene caricato in memoria quando si preme «Genera», da dove arriva, quanto occupa e che ruolo ha. Tutti i numeri sono letti dai file effettivamente presenti sul disco e dalla configurazione dei modelli, non dalla documentazione.

Profilo rilevato: lite GPU: GTX 1660 Ti · 6 GB Radice pesi: weights/

00Mappa dei componenti

Diff-FIT non è un modello unico: è una catena di componenti specializzati, ciascuno attivo solo in certe pipeline. Questa tabella dice chi entra in funzione e quando.

Componente Ruolo Attivo in Profilo
SD 1.5 · Dreamshaper 8 inpainting Sintesi e riscrittura locale dell'immagine Genera, Img2Img, Inpaint, EVC, Transform (ripiego) lite
RealVisXL V5.0 Lightning Sintesi ad alta risoluzione, pochi passi Genera, Img2Img full
BiSeNet + ResNet Segmentazione del volto in 19 classi → maschere Inpaint, Transform sempre
dlib · 68 landmark Punti chiave → frecce e maschera degli slider Transform sempre
Lightning Drag (5 repo) Editing geometrico punto-a-punto Transform full
Mapper EVC Metafile genetico → prompt (deterministico) AiDNA EVC sempre
Modelli hosted OpenRouter Sintesi ed editing delegati al cloud Tutti i tab in modalità OpenRouter cloud
Nota di lettura

«sempre» significa che il componente gira in locale anche in modalità OpenRouter: la segmentazione e i landmark non vengono mai delegati al cloud, perché servono a costruire la maschera che poi limita la modifica.

01Inventario dei pesi

Quello che c'è davvero sul disco in profilo lite. I pesi vivono fuori dai container Docker, su un volume dell'host, così sopravvivono a rebuild e riavvii.

File Byte Circa Contenuto
generation/dreamshaper-8-inpainting/unet/ 3.438.225.152 3,44 GB U-Net di denoising
…/safety_checker/ 1.215.979.664 1,22 GB Classificatore NSFW — disattivato a runtime
…/text_encoder/ 492.265.168 492 MB Encoder di testo CLIP
…/vae/ 334.643.268 335 MB Autoencoder immagine ↔ latente
face_landmarks/shape_predictor_68_face_landmarks.dat 99.693.937 99,7 MB Predittore dei 68 punti
resnet/resnet18.pt 55.361.505 55,4 MB Backbone del face parser
~/.cache/openrouter-fit/resnet34.onnx ~85 MB Parser ONNX, scaricato al primo uso
Un dettaglio che torna utile

I pesi su disco sono in float32: lo script di download esclude di proposito le varianti fp16 (*fp16.safetensors), che sui CDN danno spesso errori. Di conseguenza il numero di parametri di ogni componente si ricava dividendo la dimensione del file per 4 byte — ed è così che sono stati ottenuti i conteggi nelle sezioni successive.

Totali

  • Profilo lite: ~5,2 GB di modello di generazione più ~155 MB tra landmark e backbone.
  • Profilo full: circa 20 GB, per via dello stack SDXL e dei cinque repository di Lightning Drag.

02Profilo lite · SD 1.5 Dreamshaper 8 inpainting

È il modello che gira in tutte le demo di questa presentazione. Non è Stable Diffusion 1.5 «di serie»: è un fine-tuning fotorealistico (Dreamshaper 8) nella sua variante inpainting, scelta perché un solo checkpoint copre sia la generazione da zero sia la riscrittura di una zona mascherata.

Pipeline diffusers

StableDiffusionInpaintPipeline

repo
Lykon/dreamshaper-8-inpainting
ripiego
runwayml/stable-diffusion-inpainting se il primo non è raggiungibile
versione diffusers
salvato con 0.21.0.dev0
componenti
VAE · U-Net · CLIPTextModel · CLIPTokenizer · scheduler · safety checker
scheduler nel repo
DEISMultistepScheduler — sostituito all'avvio, vedi §08
risoluzione nativa
512 × 512

Il file weights/generation/active_lite_model.txt registra quale dei due candidati è stato effettivamente scaricato: serve a rendere ricostruibile a posteriori quale checkpoint ha prodotto una certa immagine.

03VAE e spazio latente

Il VAE è il traduttore tra pixel e spazio latente. Comprime l'immagine in una rappresentazione molto più piccola su cui avviene tutta la diffusione, e sa poi ricostruirla. È il motivo per cui generare a 512 × 512 è praticabile su una scheda consumer.

Autoencoder

AutoencoderKL

canali in / out
3 → 3 (RGB)
canali latenti
4
block_out_channels
[128, 256, 512, 512]
fattore di scala
8× per lato — tre stadi di riduzione
scaling_factor
0.18215
parametri
83,7 milioni (334.643.268 / 4)

Il conto della compressione

Un'immagine 512 × 512 × 3 sono 786.432 valori. Il latente corrispondente è 64 × 64 × 4, cioè 16.384 valori: un fattore 48×. La U-Net lavora su quest'ultimo, e ogni passo di denoising costa quindi quasi cinquanta volte meno di quanto costerebbe sui pixel.

Verifica incrociata

Il campo sample_size: 64 nella configurazione della U-Net conferma la riduzione: 512 ÷ 8 = 64. I tre stadi di downsampling del VAE danno esattamente 2³ = 8.

04La U-Net e i suoi 9 canali

È il cuore del modello e il file più pesante: la rete che, dato un latente rumoroso e il testo, prevede il rumore da togliere. Ha forma a «U» — prima riduce la risoluzione per cogliere la struttura d'insieme, poi la risale per recuperare il dettaglio, con collegamenti diretti tra i due rami.

Rete di denoising

UNet2DConditionModel

canali in ingresso
9 — non 4, vedi sotto
canali in uscita
4 (il rumore stimato sul latente)
sample_size
64 (latente di un'immagine 512²)
block_out_channels
[320, 640, 1280, 1280]
layers_per_block
2
attention_head_dim
8
cross_attention_dim
768 — combacia con l'uscita di CLIP
parametri
859,6 milioni (3.438.225.152 / 4)

Perché nove canali di ingresso

Una U-Net di sola generazione ne avrebbe quattro, quanti i canali latenti. La variante inpainting ne prende nove perché a ogni passo riceve tre cose concatenate:

CanaliContenutoA cosa serve
4Latente rumoroso corrente Lo stato da ripulire, come in qualsiasi diffusion
4Latente dell'immagine originale mascherata Il contesto da preservare: cosa c'era intorno al buco
1Maschera ridotta alla scala del latente Dove intervenire e dove no

È questa struttura a rendere l'inpainting nativo invece che simulato: il modello sa fin dal primo passo quali pixel deve inventare e quali deve rispettare. La ricomposizione finale col bordo sfumato è una garanzia in più, non il meccanismo principale.

Conseguenza pratica

Usare un checkpoint inpainting anche per la generazione da zero significa passare una maschera completamente bianca e un contesto vuoto. Costa qualche canale in più di calcolo, ma evita di tenere in VRAM due modelli distinti — che su 6 GB non ci starebbero.

05Encoder di testo CLIP

Traduce il prompt in una sequenza di vettori che la U-Net consulta a ogni passo tramite cross-attention. È il meccanismo per cui la parola «barba» agisce sul mento e non sulla fronte: per ogni zona dell'immagine la rete pesa quali token del prompt sono rilevanti.

Condizionamento testuale

CLIPTextModel — ViT-L/14, torre testuale

hidden_size
768
livelli
12
teste di attenzione
12
lunghezza massima
77 token
vocabolario
49.408 token (BPE)
parametri
123,1 milioni (492.265.168 / 4)
Limite da conoscere

Il tetto di 77 token include i marcatori di inizio e fine, quindi lo spazio utile è di circa 75. I prompt di Diff-FIT sono lunghi: attributi, descrizione libera e la coda di vincoli forensi («passport photo, front view, both ears visible…»). Ciò che eccede viene troncato in silenzio. È il motivo per cui i vincoli stanno in fondo e gli attributi in testa: se qualcosa deve cadere, meglio che sia la formula di inquadratura e non il colore degli occhi.

06Precisione numerica

I pesi stanno su disco in float32 ma vengono convertiti al caricamento. La scelta non è fissa: dipende dalla compute capability della scheda.

# diff_fit/generation_utils/face_generation_utils.py
def _sd15_torch_dtype() -> torch.dtype:
    """GTX 16xx / Turing (CC < 8) often NaNs the SD1.5 VAE in fp16 → black images."""
    if torch.cuda.is_available():
        major, _ = torch.cuda.get_device_capability()
        if major < 8:
            return torch.float32
    return torch.float16

Su schede con compute capability inferiore a 8 — Pascal e Turing, quindi tutta la serie GTX 16xx e le RTX 20xx — il decoder del VAE in mezza precisione produce valori che vanno in overflow e diventano NaN. L'effetto visibile è un'immagine completamente nera: non un errore, non un'eccezione, solo un rettangolo vuoto.

HardwareCCdtypeEffetto
GTX 1650 / 1660 / 1660 Ti7.5float32 Più VRAM occupata, ma immagini corrette
RTX 20xx7.5float32Idem
RTX 30xx / 40xx8.6 / 8.9float16 Metà memoria, nessun artefatto
A100 / H1008.0 / 9.0float16Idem
Perché è rilevante qui

La demo gira su una GTX 1660 Ti, quindi in float32. Su 6 GB di VRAM è il vincolo che rende necessario lo scarico dei pesi sulla CPU (DIFF_FIT_LOW_VRAM=1) e che esclude il profilo full.

07Profilo full · SDXL

Il profilo di riferimento del paper. Non era eseguibile sulla macchina di questa presentazione, ma è quello per cui Diff-FIT è stato progettato.

Generazione ad alta risoluzione

RealVisXL V5.0 Lightning

repo
SG161222/RealVisXL_V5.0_Lightning
selettore
--model lightning5
base
SDXL, fine-tuning fotorealistico, distillato «Lightning»
risoluzione
1024 × 1024
precisione
float16 con variant="fp16"
VRAM consigliata
≥ 16 GB senza offload

Il VAE sostituito

Con SDXL il codice non usa il VAE del checkpoint: ne carica uno diverso, madebyollin/sdxl-vae-fp16-fix. Il VAE originale di SDXL soffre dello stesso problema di overflow visto al §06, ma in modo strutturale e non legato alla scheda; questa versione ricalibrata lo evita permettendo di restare in float16 e dimezzare la memoria.

Le altre scelte disponibili

SelettoreRepositoryNota
liteLykon/dreamshaper-8-inpaintingdefault, ~2 GB scaricati
1.5runwayml/stable-diffusion-v1-5base non fine-tuned
realVisSG161222/Realistic_Vision_V6.0_B1_noVAESD 1.5 fotorealistico
XLstabilityai/stable-diffusion-xl-base-1.0SDXL di serie
turboSG161222/RealVisXL_V3.0_Turbopochissimi passi
lightning4SG161222/RealVisXL_V4.0_Lightninggenerazione precedente
lightning5SG161222/RealVisXL_V5.0_Lightningconsigliato in full
fluxblack-forest-labs/FLUX.1-schnellarchitettura diversa

08Gli otto scheduler

Lo scheduler decide la traiettoria del denoising: quanto rumore togliere a ogni passo e come distribuire i passi lungo il percorso. Non cambia i pesi, cambia il modo di percorrerli — e quindi qualità e velocità a parità di modello.

Chiave API Classe diffusers Comportamento
singleDPMSolverSinglestepScheduler Default. lower_order_final=True. Miglior compromesso qualità/velocità
single_karrasDPMSolverSinglestepScheduler Come sopra con use_karras_sigmas=True
multiDPMSolverMultistepScheduler Riusa le stime precedenti: converge meglio con molti passi
multi_karrasDPMSolverMultistepScheduler Multi-step con sigma di Karras
EulerEulerDiscreteScheduler Integrazione classica: semplice e riproducibile
sdeDPMSolverSDEScheduler Stocastico: reinietta rumore a ogni passo. Meno deterministico
sde_karrasDPMSolverSDEScheduler Stocastico con sigma di Karras
TCDTCDScheduler Trajectory Consistency Distillation, pensato per 4–8 passi

Che cosa sono i «sigma di Karras»

Sono una distribuzione non uniforme dei livelli di rumore lungo i passi. Invece di scendere linearmente, concentrano i passi dove la stima è più delicata — verso la fine, quando si definisce il dettaglio. A parità di numero di passi si ottengono in genere transizioni più morbide.

Una correzione applicata all'avvio

Il checkpoint Dreamshaper dichiara nel proprio config uno scheduler DEIS, incompatibile con i solver DPM. Il codice riscrive la configurazione prima di costruirli:

if cfg.get("algorithm_type") in ("deis", "deis-dpm"):
    cfg["algorithm_type"] = "dpmsolver++"
if cfg.get("final_sigmas_type") == "zero":
    cfg["final_sigmas_type"] = "sigma_min"

Senza questo adattamento gli scheduler DPM non si costruirebbero, e la scelta nell'interfaccia sarebbe inerte. TCD ed Euler invece partono dalla configurazione originale, non da quella corretta.

09Parser facciale

Assegna a ogni pixel una delle 19 classi facciali. È ciò che trasforma «voglio cambiare i capelli» in una maschera binaria. Esistono due implementazioni nello stesso progetto, e la differenza conta.

Backend locale

BiSeNet + ResNet-18 · PyTorch

pesi
weights/resnet/resnet18.pt
dimensione
55,4 MB
origine
Google Drive, scaricato da weights_download
runtime
PyTorch, sulla stessa GPU della generazione
Backend OpenRouter

BiSeNet + ResNet-34 · ONNX

file
resnet34.onnx
origine
release weights di yakhyo/face-parsing
verifica
SHA-256 controllato dopo il download
runtime
ONNX Runtime su CPU, nessuna GPU

La seconda esiste perché il servizio OpenRouter deve poter girare su una macchina senza scheda video: la segmentazione resta locale anche quando la generazione è delegata al cloud, e quindi deve costare poco.

Il preprocessing

PassoDettaglio
Ridimensionamento512 × 512, interpolazione bilineare
Normalizzazionevalori in [0,1], poi media e deviazione standard per canale
Layoutda HWC a CHW, batch di 1, float32
Uscitamappa di etichette, riportata alla risoluzione originale
Verifica SHA-256

Il checkpoint ONNX viene scaricato a runtime e confrontato con un digest atteso, scritto nel sorgente. Se non combacia, il file viene scartato e il parser fallisce con un errore esplicito. Per uno strumento forense la catena di custodia dei pesi conta quanto quella dei dati.

10Le 19 classi e le regioni dell'interfaccia

Lo schema di classi arriva da CelebAMask-HQ: 30.000 volti annotati a mano. Il parser predice queste etichette, e l'interfaccia le raggruppa in regioni utilizzabili.

0 background 1 skin 2 brow L 3 brow R 4 eye L 5 eye R 6 glasses 7 ear L 8 ear R 9 earrings 10 nose 11 mouth 12 lip up 13 lip low 14 neck 15 necklace 16 clothes 17 hair 18 hat
Regione (UI) Etichette Osservazioni
Capelli17Una sola classe, la più netta
Sopracciglia2, 3Le due metà unite
Occhi4, 5, 6 Include gli occhiali: cambiando gli occhi si riscrive anche la montatura
Naso10
Orecchie7, 8, 9Include gli orecchini
Labbra11, 12, 13Bocca e i due labbri
Incarnato1Tutta la pelle del viso
Barba Non è una classe. Vedi sotto
Il caso «Barba»

CelebAMask-HQ non ha un'etichetta per la barba, quindi non può averla nemmeno il parser. Diff-FIT la ricava geometricamente: prende la classe skin e ne conserva la porzione inferiore, ottenendo un'area che approssima mento, guance basse e baffi.

La conseguenza pratica è che la maschera «Barba» è meno precisa delle altre e non segue il bordo reale dei peli: è una regione plausibile, non una segmentazione. Sui volti glabri seleziona comunque la parte bassa del viso.

11Landmark facciali

Il predittore che individua 68 punti chiave del volto. Alimenta gli slider del tab Transform: uno spostamento diventa un insieme di frecce punto-a-punto più il rettangolo che le contiene, cioè la maschera.

Allineamento facciale

dlib · shape_predictor_68_face_landmarks

file
weights/face_landmarks/shape_predictor_68_face_landmarks.dat
dimensione
99.693.937 byte — 99,7 MB
metodo
Ensemble di alberi di regressione in cascata
hardware
Nessuna GPU: gira su CPU
tempo misurato
1,0 s per chiamata via API, di cui la predizione è una frazione
override
variabile FACE_LANDMARKS_PATH

Come si passa dallo slider alla freccia

  • Ogni slider dichiara una regione e un asse — per esempio «mascella · verticale» agisce sui punti del contorno mandibolare lungo y.
  • Il valore dello slider (da −40 a +40, o −10/+10 per la dimensione degli occhi) diventa lo spostamento applicato a quei punti.
  • Da ogni punto originale e dal suo corrispondente spostato nasce una coppia: origine in rosso, destinazione in blu.
  • Il rettangolo che contiene tutti i punti coinvolti diventa la maschera dell'area da rigenerare — il riquadro verde visibile sul canvas.

Se il file dei landmark manca, l'API espone landmarks_available: false con la relativa motivazione, e gli slider premade smettono di funzionare: restano il pennello e le frecce manuali.

12Lo stack Lightning Drag

L'editing geometrico del paper non è un modello ma un insieme di cinque repository che vengono scaricati insieme, solo in profilo full. È la voce che porta il download complessivo a circa 20 GB.

RepositoryRuolo nello stack
LightningDrag/lightning-drag-sd15 I pesi specifici del drag: data un'immagine e le coppie di punti, producono direttamente il risultato senza ottimizzazione a runtime
Lykon/dreamshaper-8-inpainting Il modello di base su cui il drag opera — lo stesso del profilo lite
h94/IP-Adapter Inietta le feature di un'immagine di riferimento via cross-attention: tiene ferma l'identità mentre i tratti si spostano
latent-consistency/lcm-lora-sdv1-5 Adattatore LoRA che porta l'inferenza a ~8 passi invece di 25–50. È ciò che rende il drag «lightning»
stabilityai/sd-vae-ft-mse VAE riaddestrato con perdita MSE: ricostruzioni più fedeli, importante quando si ricompone una zona modificata
Perché un LoRA e non un altro modello

Un Low-Rank Adaptation è un piccolo insieme di matrici a rango ridotto che si somma ai pesi esistenti. Occupa pochi MB e si innesta su un checkpoint già addestrato senza rimpiazzarlo: si può attivare per il drag e disattivare per la generazione normale, tenendo un solo modello di base in memoria.

13Il ripiego testuale del Transform

Quando Lightning Drag non è disponibile — profilo lite, oppure modalità OpenRouter — il tab Transform non si limita a spegnersi: il backend prende una strada diversa, dichiarata nel codice come _transform_via_img2img().

PassoOperazione
1Dagli offset degli slider si ricavano le coppie di punti sui landmark
2Le coppie vengono descritte a parole: «move the jawline slightly downward (strong); narrow the jawline width (moderate)…»
3Dai punti si costruisce la maschera; se mancano, si ripiega sulle regioni del parser
4Si applica una img2img limitata a quella maschera
5Si ricompone sull'originale con bordo sfumato
Limite osservato

Non è un drag geometrico: è una riscrittura locale guidata dal testo, e la sua tenuta dipende interamente da quanto il modello sottostante sa seguire istruzioni spaziali. Con SD 1.5 in profilo lite il risultato degrada visibilmente — nelle prove la zona della bocca si sfalda in un artefatto. Con un modello hosted più capace la stessa richiesta produce uno spostamento pulito.

È il motivo per cui il paper prescrive Lightning Drag e non un ripiego testuale: sotto una certa capacità del modello, il drag simulato non è utilizzabile.

Discrepanza fra interfaccia e backend

In modalità locale + lite l'interfaccia disabilita il pulsante e avvisa che il Transform non funziona (dragUnavailable in web/src/App.tsx). Il backend però risponde correttamente alle chiamate dirette a POST /api/transform. Gli slider, intanto, disegnano regolarmente frecce e maschera sul canvas anche in lite: è solo l'invio a essere bloccato.

14Il mapper EVC

È il punto di giunzione con la pipeline genetica AiDNA, e l'unico componente della catena che non è un modello.

Traduzione deterministica

fit_shared/evc_mapper.py

tipo
Codice a regole fisse — nessuna rete, nessun peso
ingresso
Metafile JSON completo, o il solo blocco evc
uscita
Prompt in linguaggio naturale
endpoint
POST /api/generate/evc su entrambi i backend
condiviso
Stesso modulo per locale e OpenRouter

Cosa sa tradurre

Campo del metafileValori riconosciuti
pigmentation.eye_colorblue · brown · green · intermediate
pigmentation.hair_colorblonde · brown · black · red · gray · white
pigmentation.skin_colorvery_light · light · intermediate · dark · dark_brown · black
age.predicted_yearsnumero intero di anni
sex.calledmale · female
markers_extrabaldness · freckles · myopia · smoking
Perché deterministico

Un modello che «interpretasse» il metafile renderebbe impossibile spiegare perché il prompt contiene una certa parola. Con un mapper a regole si può sempre risalire dal testo generato al campo JSON che lo ha prodotto — requisito minimo perché un identikit sia ispezionabile.

Quello che va perso

Il metafile porta distribuzioni di probabilità («blue 0.72, intermediate 0.18, brown 0.10») ma il mapper usa solo il valore più probabile. L'incertezza non entra nell'immagine: si vede solo nella divergenza tra le varianti generate, che però dipende dal rumore iniziale e non dalle probabilità. Campionare i tratti secondo la loro distribuzione sarebbe il passo successivo naturale.

15Modelli hosted

In modalità OpenRouter la generazione viene delegata. Cambiano il costo, la latenza e soprattutto il perimetro dei dati; restano locali il parser e i landmark.

Slug OpenRouter Etichetta Nota
google/gemini-3.1-flash-image-20260528Nano Banana 2 · Flashdefault
google/gemini-3-pro-image-20260528Nano Banana Proqualità massima
google/gemini-3.1-flash-lite-image-20260630Nano Banana 2 Liteeconomico
google/gemini-2.5-flash-imageNano Bananagenerazione precedente
black-forest-labs/flux.2-klein-4bFLUX.2 Klein 4B~$0,014 per megapixel
bytedance-seed/seedream-4.5Seedream 4.5$0,04 per immagine
openai/gpt-image-1-miniGPT Image 1 Mini

L'inpainting emulato

Nessuno di questi modelli accetta una maschera binaria: rigenerano l'intera immagine a partire da un prompt. Diff-FIT ricostruisce il comportamento dell'inpainting in tre mosse: segmenta in locale, invia immagine e istruzione localizzata, poi ricompone solo dentro la maschera con bordo sfumato. Fuori dalla maschera i pixel restano quelli di partenza, esattamente come nel percorso locale — ma la garanzia arriva dalla ricomposizione, non dal modello.

Perimetro dei dati

In questa modalità il volto sotto esame lascia la macchina. La chiave API vive nel localStorage del browser e viaggia nell'header X-OpenRouter-Key, oppure sta in una variabile d'ambiente lato server. Per materiale coperto da segreto istruttorio la modalità locale non è una preferenza ma un requisito.

16Riferimenti

Identificativo Lavoro Dove interviene
10.1109/ACCESS.2026.3672229 Tomašević, Peer, Štruc, Miočić — Diff-FIT, IEEE Access 2026 Il sistema nel suo insieme
arXiv:2112.10752 Rombach et al. — Latent Diffusion Models, CVPR 2022 §02 §03 §04 — l'architettura di base
arXiv:1512.03385 He et al. — Deep Residual Learning, CVPR 2016 §09 — backbone del parser
arXiv:1808.00897 Yu et al. — BiSeNet, ECCV 2018 §09 — la rete di segmentazione
arXiv:1907.11922 Lee et al. — MaskGAN / CelebAMask-HQ, CVPR 2020 §10 — lo schema a 19 classi
arXiv:2405.13722 Shi et al. — LightningDrag, 2024 §12 — l'editing a trascinamento
arXiv:2306.14435 Shi et al. — DragDiffusion, CVPR 2024 §12 — il precursore
arXiv:2308.06721 Ye et al. — IP-Adapter, 2023 §12 — conservazione dell'identità
arXiv:2311.05556 Luo et al. — LCM-LoRA, 2023 §12 — inferenza in pochi passi
CVPR 2014 Kazemi & Sullivan — Face Alignment with Regression Trees §11 — i 68 landmark

I PDF sono nella cartella papers/ del repository, con la licenza indicata per ciascuno. Il paper Diff-FIT è CC BY 4.0.