Vai al contenuto
coden

Modelli di diffusione: come il rumore puro diventa un’immagine

Il processo diretto che aggiunge rumore, una rete che stima il rumore, DDPM e DDIM scritti da zero, otto cluster senza collasso dei modi, quanti passi di campionamento servono, il confronto con VAE e GAN sulle cifre e la strada verso le immagini da un testo.

12 minuti Matěj Žalmánek 2026-10-16

Serie Basi di IA Parte 46 di 52
  1. Mappa dell’intelligenza artificiale: che cos’è ciascuna cosa e come si incastra tutto
  2. Breve storia dell’intelligenza artificiale: da Turing ai modelli linguistici
  3. Dati, modello, addestramento, inferenza: i concetti di base su un unico esempio
  4. Come leggere la notazione matematica: simboli, indici, sommatorie e quantificatori
  5. Insiemi e relazioni: i mattoncini con cui si costruiscono le definizioni nell’IA
  6. Funzioni e applicazioni: perché ogni modello di IA è una funzione
  7. Logica e dimostrazioni: le regole con cui si ragiona nell’IA
  8. Grafi e alberi: la struttura su cui poggiano la ricerca e le reti neurali
  9. Algebra lineare per l’apprendimento automatico: vettori, matrici e perché l’IA soprattutto moltiplica
  10. Derivate, gradiente e regola della catena: come un modello capisce in quale direzione imparare
  11. Discesa del gradiente: come impara un modello
  12. Che cos’è la probabilità: dal lancio di un dado agli assiomi di Kolmogorov
  13. Probabilità condizionata e teorema di Bayes: come cambiare una stima quando scopri qualcosa di nuovo
  14. Variabile aleatoria e funzione di ripartizione: una sola funzione che dice tutto sulla distribuzione
  15. Funzione di densità e funzione di massa: perché una variabile continua ha probabilità zero in un punto
  16. Valore atteso, varianza e covarianza: dove si trova una distribuzione, quanto è larga e che cosa è legato a che cosa
  17. Panoramica delle distribuzioni di probabilità: Bernoulli, binomiale, Poisson, uniforme, normale ed esponenziale
  18. Legge dei grandi numeri e teorema del limite centrale: perché le medie si comportano in modo così prevedibile
  19. Statistica e stima dei parametri: massima verosimiglianza, MAP e intervalli di confidenza
  20. Teoria dell’informazione: entropia, entropia incrociata e divergenza KL — da dove vengono le funzioni di perdita
  21. Ricerca nello spazio degli stati: BFS, DFS, UCS e A* con animazioni
  22. Giochi e avversari: minimax, potatura alfa-beta e Monte Carlo tree search
  23. Soddisfacimento di vincoli: backtracking, propagazione dei vincoli e AC-3 su un sudoku e una mappa delle regioni ceche
  24. Logica e sistemi basati sulla conoscenza: concatenazione in avanti e all’indietro, risoluzione e sistemi esperti
  25. Pianificazione: STRIPS, il mondo dei blocchi, euristiche dal rilassamento e pianificazione negli agenti IA
  26. Ricerca locale e ricottura simulata: un commesso viaggiatore tra i capoluoghi di regione cechi
  27. Algoritmi genetici: popolazione, incrocio, mutazione e selezione su uno zaino per l’escursione
  28. Strategie evolutive e programmazione genetica: dalla regola di un quinto alla legge di Keplero
  29. Ottimizzazione con colonie di formiche: come una traccia di feromone trova un percorso breve
  30. Ottimizzazione a sciame di particelle: inerzia, esperienza propria ed esperienza dello sciame
  31. Neuroevoluzione: evoluzione dei pesi e della forma delle reti neurali e l’algoritmo NEAT
  32. Insiemi fuzzy e funzioni di appartenenza: come scrivere «un po’ caldo»
  33. Logica fuzzy e probabilità: perché «un po’ caldo» non significa «probabilmente caldo»
  34. Logica fuzzy: t-norme, implicazioni e regole SE–ALLORA
  35. Controllo fuzzy: Mamdani e Sugeno, dal ventilatore al pendolo inverso su un carrello
  36. Clustering fuzzy: l’algoritmo fuzzy c-means e i punti tra i cluster
  37. Sistemi neuro-fuzzy (ANFIS): regole fuzzy che imparano dai dati
  38. Catene di Markov: matrice di transizione, distribuzione stazionaria e PageRank
  39. Modelli di Markov nascosti: l’algoritmo di Viterbi e il casinò disonesto
  40. Reti bayesiane: perché l’erba è bagnata e che cosa significa per l’irrigatore
  41. Filtro di Kalman: come stimare da misure imprecise dove si trova un’auto e a che velocità va
  42. Tipi di apprendimento automatico: supervisionato, non supervisionato, semi-supervisionato e altri
  43. Prompt, contesto e RAG: come dare a un modello le informazioni giuste
  44. Autoencoder variazionali (VAE): immagini nuove da uno spazio latente continuo
  45. Reti generative avversarie (GAN): il falsario contro il detective
  46. Modelli di diffusione: come il rumore puro diventa un’immagine
  47. Processi decisionali di Markov: stati, azioni, ricompense ed equazioni di Bellman
  48. Q-learning e DQN: imparare il valore delle azioni, dalla tabella alla rete neurale
  49. Policy gradient e PPO: imparare direttamente la politica
  50. Come funziona un agente IA: un modello linguistico in un ciclo con strumenti
  51. Programmare con agenti IA: incarico, test e controllo
  52. Valutazione e sicurezza dei sistemi di IA: come misurare e come sorvegliare

Programma completo della serie 52 di 83 argomenti pubblicati

Cosa porterai a casa
  • Come funzionano il processo diretto e quello inverso della diffusione.
  • Perché la diffusione si addestra in modo più stabile di un GAN e quanto costa il numero di passi.
  • Come la diffusione diventa un generatore di immagini a partire da un testo.

Utile sapere prima: Reti generative avversarie (GAN): il falsario contro il detective, Autoencoder variazionali (VAE): immagini nuove da uno spazio latente continuo

Stable Diffusion, Midjourney, DALL·E 3 e i modelli che generano video si basano tutti sulla stessa idea, ed è sorprendentemente semplice. Distruggere un’immagine è facile — basta aggiungerle gradualmente rumore finché non resta solo rumore. Se imparassimo ad annullare ogni piccolo passo, potremmo partire dal rumore puro e farne emergere un’immagine passo dopo passo. In questa parte lo programmiamo da zero e lo confrontiamo con il VAE e il GAN sugli stessi dati.

Si collega alle parti Reti generative avversarie e Autoencoder variazionali.

1. Processo diretto: l’immagine si dissolve nel rumore

Definizione — processo diretto (di diffusione)

Si sceglie un numero di passi T e un piano di piccole varianze β1, …, βT. A ogni passo si aggiunge un po’ di rumore: xt = √(1 − βt) · xt−1 + √βt · ε, ε ~ N(0, I). Componendo i passi si ottiene la forma chiusa xt = √ᾱt · x0 + √(1 − ᾱt) · ε, dove ᾱt = ∏s ≤ t (1 − βs). Per t abbastanza grande ᾱt ≈ 0 e xt è rumore puro.

In parole semplici

Una goccia d’inchiostro in un bicchiere d’acqua: per un attimo si vede la forma della goccia, poi si diffonde e alla fine l’acqua è colorata in modo uniforme e la forma originale non si riconosce più. La formula chiusa dice che si può saltare direttamente a qualsiasi istante — non serve simulare tutti i passi.

xt = √ᾱt · x0 + √(1 − ᾱt) · ε

xt
l’immagine rumorosa al passo t — esattamente ciò che la rete riceve in ingresso durante l’addestramento
√ᾱt
quanto resta dell’immagine originale; ᾱt è il prodotto di tutti gli (1 − βs) fino al passo t, quindi diminuisce a ogni passo
x0
l’immagine originale presa dai dati
√(1 − ᾱt)
quanto rumore c’è; le radici quadrate ci sono perché a sommarsi sono le varianze: (√ᾱ)² + (√(1 − ᾱ))² = 1, così dati con varianza 1 hanno varianza 1 a ogni passo e alla fine passano gradualmente a N(0, I)
ε
un campione di rumore da N(0, I) — proprio ciò che la rete dovrà indovinare; il fatto che lo conosciamo trasforma l’addestramento in una normale regressione
Teorema — perché basta un solo salto

Se vale xt−1 = √ᾱt−1 x0 + √(1 − ᾱt−1) ε′ con ε′ ~ N(0, I), vale anche xt = √ᾱt x0 + √(1 − ᾱt) ε con un nuovo ε ~ N(0, I).

Dimostrazione. Sostituiamo in un passo: xt = √(1 − βt) √ᾱt−1 x0 + √(1 − βt) √(1 − ᾱt−1) ε′ + √βt ε″. Il primo termine è √ᾱt x0, perché ᾱt = (1 − βt) ᾱt−1. Gli altri due sono rumori normali indipendenti con media 0; la loro somma è di nuovo normale e le varianze si sommano: (1 − βt)(1 − ᾱt−1) + βt = 1 − (1 − βt) ᾱt−1 = 1 − ᾱt. Per t = 1 l’affermazione vale direttamente (ᾱ0 = 1), il resto segue per induzione. ∎

Esempio — il nostro piano del rumore in numeri

β cresce linearmente: βt = β1 + (βT − β1) · (t − 1)/(T − 1), cioè di 0,00101 a ogni passo.

tβtᾱt√ᾱt (segnale)√(1 − ᾱt) (rumore)
10,000100,99991,0000,010
20,001110,99880,9990,035
250,024320,73510,8570,515
370,036430,50450,7100,704
380,037440,48560,6970,717
500,049550,28300,5320,847
1000,100000,00560,0750,997

Verifichiamo a mano la seconda riga: ᾱ2 = (1 − β1)(1 − β2) = 0,9999 · 0,99889 = 0,99879. Segnale e rumore si equivalgono (ᾱ = 0,5) tra i passi 37 e 38; al passo 100 l’immagine originale ha un peso di appena 0,075 contro 0,997 del rumore.

Nel nostro caso T = 100 e β cresce linearmente da 0,0001 a 0,1. La quota del segnale originale √ᾱt è 0,86 al passo 25, 0,53 al passo 50 e appena 0,07 al passo 100.

Un tre nel processo diretto (da sinistra t = 0, 10, 25, 50, 75, 100)

2. Processo inverso: una rete che indovina il rumore

Definizione — DDPM (denoising diffusion probabilistic model)

DDPM (Jonathan Ho, Ajay Jain e Pieter Abbeel, 2020; idea di Jascha Sohl-Dickstein e colleghi, 2015) addestra una rete εθ(xt, t) a stimare, da un’immagine rumorosa e dal numero del passo, quale rumore ε è stato aggiunto. La perdita è il normale errore quadratico medio E ‖ε − εθ(√ᾱt x0 + √(1 − ᾱt) ε, t)‖² con t casuale. Si campiona all’indietro a partire da xT ~ N(0, I): xt−1 = (xt − βt/√(1 − ᾱt) · εθ) / √(1 − βt) + √βt · z.

In parole semplici

La rete riceve una foto sfocata e rumorosa e la domanda «quanto rumore c’è dentro e che aspetto ha?». Se sa stimarlo, sa anche toglierne un po’. Ripetiamo cento volte, ogni volta con un pizzico di casualità fresca — e dal rumore emerge un’immagine. L’addestramento è una normale regressione: nessun avversario come nel GAN, nessun compromesso come nel VAE.

L(θ) = Ex0, t, ε ‖ε − εθ(√ᾱt x0 + √(1 − ᾱt) ε, t)‖²

ε
il rumore che abbiamo aggiunto noi stessi all’immagine — la risposta corretta, ed è per questo che la conosciamo senza alcuna etichettatura dei dati
εθ(…, t)
la stima del rumore fatta dalla rete; riceve anche il numero del passo t, perché con t = 2 deve trovare poco rumore e con t = 100 xt è quasi solo rumore
√ᾱt x0 + √(1 − ᾱt) ε
l’immagine rumorosa xt prodotta con un solo salto — grazie alla formula chiusa basta estrarre t ed ε per ogni esempio, non si simula nulla passo dopo passo
Il valore atteso è sulle immagini dei dati, su un passo t ∈ {1, …, T} estratto uniformemente e sul rumore ε ~ N(0, I); in pratica è una media sul batch. Ho e colleghi hanno ottenuto questa perdita semplice semplificando il limite inferiore variazionale (quello che ottimizza anche il VAE) — ne hanno eliminato i pesi dei singoli passi.

xt−1 = 1/√(1 − βt) · (xt − βt/√(1 − ᾱt) · εθ(xt, t)) + √βt · z

xt
lo stato rumoroso attuale — si parte dal rumore puro xT ~ N(0, I)
εθ(xt, t)
la stima del rumore presente in xt
βt/√(1 − ᾱt)
quanta parte del rumore stimato togliere — solo la quota che corrisponde a un passo (βt), riportata al livello complessivo di rumore √(1 − ᾱt); nel nostro caso 0,01 al passo 1 e 0,10 al passo 100
1/√(1 − βt)
annulla la riduzione del passo diretto (lì si moltiplicava per √(1 − βt)); al passo 100 vale 1,054
√βt · z
rumore fresco z ~ N(0, I) (all’ultimo passo z = 0) — il processo inverso è casuale come quello diretto; senza di esso i campioni verrebbero attirati verso immagini medie. L’ampiezza √βt è una delle due scelte provate da Ho e colleghi
La parentesi moltiplicata per il primo fattore è una stima della media di un’immagine con un passo di rumore in meno; poi le si aggiunge tanta casualità quanta ne spetta al passo.
# addestramento (DDPM)
ripeti 16 000×:
    per ciascuno dei 64 esempi del batch:
        x₀ = esempio casuale dai dati
        t  = a caso tra 1 … 100
        ε  = vettore di numeri casuali da N(0, 1)
        x_t = √ᾱ_t · x₀ + √(1 − ᾱ_t) · ε
        errore = ‖ε − ε_θ(x_t, codice(t))‖² / dimensione
    passo di Adam sull’errore medio

# campionamento (DDPM, 100 passi)
x = vettore da N(0, 1)
per t = 100, 99, …, 1:
    ε̂ = ε_θ(x, codice(t))
    z = vettore da N(0, 1), zero al passo t = 1
    x = (x − β_t / √(1 − ᾱ_t) · ε̂) / √(1 − β_t) + √β_t · z
restituisci x
Definizione — codifica sinusoidale del tempo

La rete non riceve direttamente il numero t, ma otto numeri codice(t) = (sin(fπt/T), cos(fπt/T)) per f = 1, 2, 4, 8. Le frequenze lente dicono «più o meno a che punto del processo siamo», quelle rapide distinguono passi vicini; tutti i numeri sono tra −1 e 1, così nessun ingresso prevale sugli altri.

Per t = 25 (un quarto del processo, angoli π/4, π/2, π e 2π): codice(25) = (0,707; 0,707; 1,000; 0,000; 0,000; −1,000; 0,000; 1,000).

La nostra rete è la normale rete multistrato della parte sui GAN: in ingresso xt e otto numeri della codifica sinusoidale del tempo t (come la codifica posizionale in un transformer), in uscita la stima del rumore. Sul cerchio ha due strati nascosti da 64 neuroni, sulle cifre da 128. Si addestra con Adam per 16 000 passi.

3. Otto cluster senza collasso

Gli stessi dati della parte precedente: otto cluster su un cerchio. Ecco come appaiono 400 campioni durante il processo inverso:

t = 100 t = 50 t = 25 t = 10 t = 0 coordinata x₁ (senza unità) x₂ (senza unità)
Processo inverso: dal rumore (t = 100) ai dati (t = 0)

Ancora al passo 25 i punti sono sparsi in modo quasi uniforme (qualità 3 %), al passo 10 si delinea il cerchio e negli ultimi dieci passi i punti si radunano nei cluster. Alla fine sono coperti tutti gli 8 cluster e ognuno ha ricevuto da 28 a 50 dei 500 campioni. La qualità (quota entro 3σ da un centro) è 63 %.

La differenza rispetto al GAN non sta nella qualità, ma nell’affidabilità. Il GAN ha coperto tutti e otto i cluster solo in un’esecuzione su quattro; la diffusione ci è riuscita nell’unica esecuzione che abbiamo lanciato (un’esecuzione non è una prova, ma è coerente con ciò che si sa della diffusione). La perdita della diffusione infatti non è un gioco, ma una regressione, e la rete viene penalizzata per ogni campione dei dati — non può «lasciar perdere» nessun cluster.

4. Quanti passi servono

Definizione — DDIM

DDIM (Jiaming Song, Chenlin Meng e Stefano Ermon, 2020) usa la stessa rete addestrata, ma campiona in modo deterministico e a salti più grandi: dalla stima del rumore calcola una stima dell’immagine pulita x̂0 = (xt − √(1 − ᾱt) εθ) / √ᾱt e da questa direttamente xs = √ᾱs x̂0 + √(1 − ᾱs) εθ per qualsiasi tempo precedente s < t.

In parole semplici

Invece di cento passettini ne facciamo venti più lunghi. A ogni passo la rete si chiede «come sarebbe, più o meno, l’immagine finita?» e salta di conseguenza per un tratto di strada. Se i salti sono troppo grandi, la rete sbaglia mira.

xs = √ᾱs · x̂0 + √(1 − ᾱs) · εθ(xt, t),   x̂0 = (xt − √(1 − ᾱt) εθ) / √ᾱt

xt
lo stato in cui ci troviamo adesso
εθ
la stima del rumore — la stessa rete del DDPM, non si riaddestra nulla
x̂0
la stima dell’immagine finita: la formula chiusa del processo diretto risolta rispetto a x0; si divide per √ᾱt, che all’inizio è piccolo, quindi è qui che la stima è meno precisa
√ᾱs
quanta immagine deve esserci al tempo di arrivo s — lo stesso fattore del processo diretto, solo per un altro tempo
√(1 − ᾱs)
quanto rumore deve restare; il DDIM usa lo stesso rumore stimato e non ne estrae di nuovo — per questo è deterministico
Un passo è «togli tutto il rumore e poi aggiungine di nuovo fino al livello del tempo s». Così il DDIM può saltare lontano quanto vuole.
Esempio — perché due passi non bastano (in modo semplificato)

Il DDIM con n passi percorre tempi distribuiti in modo uniforme: con 5 passi 100 → 80 → 60 → 40 → 20 → 0, con 2 passi 100 → 50 → 0. Il primo salto parte sempre da t = 100, dove √ᾱ100 = 0,075.

Se la rete sbaglia la stima del rumore di δ, la stima x̂0 sbaglia di δ · √(1 − ᾱ100)/√ᾱ100 = 13,3 δ — l’errore viene amplificato più di dieci volte. Sostituendo nel salto verso il tempo s, il nuovo stato differisce da quello corretto di δ · (√(1 − ᾱs) − √ᾱs · 13,3):

  • 5 passi, salto 100 → 80: fattore −1,59,
  • 2 passi, salto 100 → 50: fattore −6,23,

Con un salto piccolo la stima sbagliata x̂0 viene mescolata con un peso piccolo √ᾱ80 = 0,19 e i passi successivi la correggono. Con un salto fino a metà del processo entra con il peso √ᾱ50 = 0,53 e resta un solo passo. Il ragionamento segue un solo errore in un solo passo e presuppone che per il resto la rete stimi con precisione; mostra però perché i primi passi, i più rumorosi, sono i più delicati.

0 %25 %50 %75 %100 % 63 · 8/8 100 79 · 8/8 50 77 · 8/8 20 70 · 8/8 10 60 · 8/8 5 0 · 0/8 2 passi di campionamento (numero) qualità (% di campioni entro 3σ)
Qualità e copertura sul cerchio in base al numero di passi di campionamento DDPM (100 passi) DDIM migliore esecuzione del GAN

Il DDIM con 50 passi raggiunge una qualità del 79 % — più del DDPM con 100 passi (63 %), molto probabilmente perché non aggiunge rumore casuale che la nostra rete imprecisa non fa in tempo a eliminare negli ultimi passi. Con 10 passi è ancora il 70 %, con 5 passi il 60 %. Con 2 passi il campionamento va in pezzi (0 %). Il numero di passi è il costo principale della diffusione: ogni passo è un passaggio attraverso la rete, mentre un GAN genera un’immagine con un solo passaggio.

5. Cifre: confronto tra tre generatori

Sulle cifre 8 × 8 (pixel riportati all’intervallo da −1 a 1) la rete si addestra per 16 000 passi.

diffusione GAN, seme 2 VAE
I primi dieci campioni
modellodistanza dalla cifra più vicinacifra meno rappresentata (su 200)cifre con meno di 10 campioni
VAE (k = 8)0,054100
GAN, seme 10,04933
GAN, seme 20,04206
diffusione (100 passi)0,063120

Qui bisogna essere onesti: la nostra diffusione ha una distanza di 0,063, peggio del VAE (0,054) e del GAN (0,042). Nelle immagini si vede un rumore residuo. La rappresentazione delle cifre però è equilibrata — la cifra meno frequente ha 12 campioni, mentre al GAN con seme 2 mancano del tutto due cifre.

Perché la nitidezza è peggiore? Una piccola rete multistrato deve togliere il rumore dalle immagini a tutti i cento livelli di rumore insieme, ed è un compito più difficile dell’unica mappatura rumore → immagine di un GAN. In compenso migliora in modo costante con il calcolo: la distanza dei campioni è scesa durante l’addestramento 0,096 (passo 4 000), 0,082 (passo 8 000), 0,068 (passo 12 000), 0,063 (passo 16 000) (stima rapida su 100 campioni DDIM con 20 passi). Nessun collasso né oscillazioni. I veri modelli di diffusione usano reti convoluzionali U-Net o transformer con centinaia di milioni di parametri e si addestrano per settimane — e allora vincono anche in nitidezza.

6. Dalle cifre alle immagini da un testo

  • Condizionamento. La rete εθ(xt, t, c) riceve in più una descrizione c — un embedding del testo prodotto da un modello linguistico, collegato tramite l’attenzione (la parte sull’attenzione). Si addestra su miliardi di coppie immagine–didascalia.
  • Guida senza classificatore (classifier-free guidance, Jonathan Ho e Tim Salimans, 2021). La rete si addestra sia con la descrizione sia senza, e durante il campionamento la stima viene spostata nella direzione «con descrizione meno senza descrizione», amplificata da un coefficiente. L’immagine corrisponde così meglio alla richiesta, al prezzo di una minore varietà.
  • Diffusione latente. La diffusione avviene nel piccolo spazio latente di un autoencoder, non nei pixel — vedi la parte sui VAE. Grazie a questo Stable Diffusion (2022) gira perfino su una scheda grafica da gioco.
  • Meno passi. Campionatori migliori e la distillazione (una rete impara a imitare molti passi in uno solo o in pochi) hanno ridotto la generazione da centinaia di passi a poche unità.

ε̃ = εθ(xt, t, ∅) + w · (εθ(xt, t, c) − εθ(xt, t, ∅))

εθ(…, ∅)
la stima del rumore senza descrizione (condizione vuota ∅) — «che aspetto ha un’immagine qualsiasi»; la rete la impara perché durante l’addestramento la descrizione viene ogni tanto scartata a caso
εθ(…, c) − εθ(…, ∅)
di quanto cambia la stima quando la rete conosce la descrizione — la direzione in cui la descrizione tira l’immagine
w
forza della guida: w = 0 ignora la descrizione, w = 1 è un normale modello condizionato, w > 1 esagera l’influenza della descrizione — l’immagine corrisponde meglio alla richiesta, ma i campioni si somigliano di più
Durante il campionamento ε̃ si usa al posto di εθ; il prezzo sono due passaggi attraverso la rete per passo. Ho e Salimans scrivono la stessa formula come (1 + w′) εθ(…, c) − w′ εθ(…, ∅), cioè w = 1 + w′. La libreria diffusers usa per Stable Diffusion il valore predefinito w = 7,5.

7. Riepilogo

  • Il processo diretto aggiunge rumore poco a poco; a qualsiasi passo si può saltare con la formula √ᾱ x₀ + √(1 − ᾱ) ε.
  • La rete impara a stimare il rumore aggiunto — una normale regressione. Si genera all’indietro a partire dal rumore puro.
  • Sugli otto cluster la diffusione li ha coperti tutti in un’unica esecuzione (DDIM con 50 passi 79 %); il GAN solo in un’esecuzione su quattro.
  • Meno passi (DDIM) accelerano il campionamento; con 10 passi la qualità è del 70 %, con 2 passi va in pezzi.
  • Sulle cifre la diffusione copre tutte le cifre, mentre in nitidezza resta indietro con la nostra piccola rete; però migliora in modo costante con il calcolo.

Vuoi metterci le mani? Fai addestrare a un agente IA un piccolo DDPM su dati bidimensionali (per esempio punti a forma delle tue iniziali) e fagli disegnare come i punti si compongono in lettere durante il processo inverso.

La vedi diversamente? Scrivi a support@coden-app.com.

Un Agente sul tuo computer, guidato dal telefono