- Python domina l'intelligenza artificiale grazie al suo ecosistema, ma GIL, la tipizzazione dinamica e l'interprete ne ostacolano le prestazioni.
- Mojo, basato su MLIR, offre compilazione, vera parallelizzazione e compatibilità con le librerie Python.
- Modular unifica i runtime per PyTorch e TensorFlow, con accelerazione e quantizzazione integrate.
- Sono possibili enormi accelerazioni (Mandelbrot, SIMD); la sfida è quella di portare questo vantaggio alla produzione e su più hardware.

Il dibattito sulle prestazioni tra Mojo e Python è acceso perché tocca il cuore dell'IA moderna: velocità reale, facilità d'uso e supporto hardware. Negli ultimi anni, sono emersi dati di accelerazione che, sulla carta, sembrano fantascienza, ma che sono supportati da profondi cambiamenti nei compilatori e nel modo in cui il codice viene eseguito su CPU, GPU e acceleratori di IA.
In questo articolo, abbiamo raccolto una panoramica completa di tutto ciò che è stato pubblicato su varie fonti riguardo a Python, ai suoi limiti prestazionali e all'approccio di Mojo , il linguaggio basato su Modular e guidato da Chris Lattner (LLVM, Clang, Swift). Spieghiamo anche MLIR, le ragioni alla base dei colli di bottiglia GIL, le differenze tra CUDA e MPS, la compatibilità con l'ecosistema Python e le sfide di adozione che ci attendono ancora.
Python domina l'intelligenza artificiale, ma la sua architettura non aiuta le prestazioni
Non sorprende che Python sia il linguaggio universale dell'IA : sintassi semplice, migliaia di librerie, tantissimi tutorial e un'enorme community. Questa popolarità, tuttavia, si accompagna a una realtà scomoda: Python è interpretato , a tipizzazione dinamica e soggetto al Global Interpreter Lock (GIL) , che limita l'esecuzione simultanea di codice Python puro a un singolo thread.
Questa architettura consente uno sviluppo più rapido, ma compromette velocità ed efficienza della memoria rispetto a linguaggi compilati come C/C++, Swift o Rust. Nei carichi di lavoro di machine learning e deep learning, dove ogni millisecondo conta e l'hardware è incredibilmente veloce, questa penalizzazione è estremamente evidente.
Per compensare, l'ecosistema ha fatto ricorso a soluzioni alternative: NumPy (con parti in C e Fortran), librerie che delegano al codice nativo ed estensioni C/C++ per le operazioni critiche. Funziona, certo, ma introduce livelli, dipendenze e un mostro di Frankenstein di versioni, framework e backend che possono essere difficili da gestire in produzione.
Inoltre, il parallelismo in Python spesso si basa sul multiprocessing o su librerie che rilasciano il GIL in sezioni native. Il risultato è che, a meno che il carico di lavoro non sia delegato in modo molto efficiente a C/C++ o alla GPU, le prestazioni pure di Python diventano un collo di bottiglia.
NumPy e altre "patch": essenziali, ma con limitazioni
NumPy ne è l'esempio classico: molte delle sue operazioni critiche sono scritte in C o Fortran , linguaggi significativamente più veloci del puro Python. Tuttavia, quando si tratta di parallelismo fine, scalabilità su più core o integrazione con nuovi acceleratori, i limiti di Python riemergono , soprattutto se il flusso di controllo ritorna frequentemente all'interprete.
Questo approccio a livelli (Python → estensioni C/C++ → driver/hardware) è efficace, ma complesso da sottoporre a debug e implementare . Nell'IA su larga scala, con pipeline di addestramento, inferenza e post-elaborazione, questa complessità operativa pesa quasi quanto le FLOPS disponibili.
CUDA, MPS e il problema della portabilità
L'accelerazione CUDA (NVIDIA) è una vera e propria ancora di salvezza, ma anche una gabbia dorata: alcuni modelli e ottimizzazioni dipendono interamente dallo stack NVIDIA. Se si tenta di eseguire lo stesso codice su Apple Silicon con Metal Performance Shaders (MPS) o su GPU AMD, si potrebbero riscontrare istruzioni non supportate o percorsi di calcolo incompleti.
Il paragone più comune è chiaro: con CUDA è come guidare una "Ferrari", mentre MPS può risultare più limitato per determinati carichi di lavoro. Ciononostante, il settore sta spingendo verso standard e portabilità perché nessuno vuole vincolare la propria attività a un singolo fornitore di hardware, a meno che non sia assolutamente necessario.
MLIR: il ponte di cui la nuova era dell'informatica aveva bisogno
Per comprendere la proposta di Mojo, è necessario parlare di MLIR (Multi-Level Intermediate Representation) , un progetto nato all'interno dell'ecosistema LLVM che aggiunge una rappresentazione intermedia progettata per alte prestazioni e apprendimento automatico . A differenza della classica pipeline LLVM, MLIR gestisce grafi di dati, vettorizzazione, tassellatura, inserimento DMA e gestione esplicita della cache.
In parole semplici: MLIR permette di trasformare codice di alto livello in implementazioni molto vicine all'hardware di destinazione (CPU, GPU, TPU, NPU, FPGA, ecc.), estraendo il parallelismo e applicando ottimizzazioni HPC che il compilatore classico non copriva altrettanto bene per questi ambiti.
Cos'è esattamente Mojo?
Mojo è un linguaggio che si presenta come un superset di Python : mantiene una sintassi familiare, può sfruttare le stesse librerie e integra un moderno modello di compilazione supportato da MLIR. È stato lanciato nel 2023, inizialmente come ambiente di sviluppo web accessibile su richiesta, e successivamente con esecuzione locale su GNU/Linux e macOS. Nel febbraio 2025, la sua libreria standard è stata resa open source, sebbene il compilatore rimanga proprietario a tutt'oggi.
L'obiettivo è ambizioso: la semplicità di Python con le prestazioni di C/C++ , oltre alla sicurezza e alla facilità d'uso che abbiamo visto in linguaggi come Rust o Swift. In altre parole, scrivere ad alto livello e produrre binari piccoli, veloci e facili da distribuire.
Chiavi di progettazione: digitazione, memoria, strutture e funzioni
Tra le caratteristiche più rilevanti figurano la tipizzazione forte (e la tipizzazione statica quando necessaria), l'uso di let/var per dichiarare elementi immutabili e mutabili e il supporto per le struct con design definiti in fase di compilazione, che facilitano la generazione di codice macchina ottimale.
Mojo permette di dichiarare funzioni con `fn` oltre a `def` ; in generale, `fn` tende a implicare maggiori restrizioni e, di conseguenza, un maggiore potenziale di ottimizzazione per il compilatore. Vanta inoltre "astrazioni a costo zero" e capacità di auto-ottimizzazione , grazie alle quali il compilatore seleziona parametri efficienti per la piattaforma di destinazione.
Senza GIL e con parallelizzazione reale
A differenza di Python, Mojo non si basa sul GIL (Global Interpreter Lock ). Il runtime e il compilatore sono progettati per sfruttare thread, vettori e acceleratori senza che lo sviluppatore debba confrontarsi con la concorrenza di base dell'interprete. In pratica, questo significa che le attività che in Python "interagiscono" con il GIL possono essere effettivamente eseguite in parallelo.
Questo punto è fondamentale nel calcolo intensivo: se si riesce a scomporre un problema in sotto-attività ed eseguirle contemporaneamente in modo nativo, il salto prestazionale non è incrementale, ma rappresenta un vero e proprio cambio di categoria.
Prestazioni: da Mandelbrot alle versioni vettorializzate
Per misurare i miglioramenti, un test ricorrente è il set di Mandelbrot , un generatore di frattali computazionalmente intensivo, perfetto per la parallelizzazione. Con Python puro, sono stati riportati tempi superiori a 1000 secondi , mentre le implementazioni in Mojo sono scese a circa 0,03 secondi dopo successive ottimizzazioni.
Sono state documentate progressioni del seguente tipo: versione Python ingenua → NumPy → versione Mojo ingenua → Mojo vettorizzato con SIMD . Con questa pipeline di miglioramenti, sono stati osservati enormi incrementi di velocità, che vanno da 35.000x a cifre riportate di 68.000x in scenari specifici. Si tratta di numeri spettacolari che, come sempre, dipendono dall'algoritmo, dall'hardware e dalla cura dedicata all'ottimizzazione.
Compilazione e distribuzione semplici
Mojo segue la filosofia "compila in binario" : compili, ottieni un eseguibile e lo distribuisci . Se provieni da Python, questo ti evita i grattacapi degli ambienti virtuali , dei pacchetti wheel e delle combinazioni di versioni di librerie che non sempre sono compatibili tra loro.
Per darvi un'idea, "Hello World" potrebbe essere compilato ed eseguito con un semplice mojo hello.mojo . Inoltre, i file hanno l' estensione .mojo (l'emoji della fiamma è diventata popolare anche come simbolo di ammiccamento), il che li rende più facili da identificare all'interno di progetti ibridi.
Compatibilità ed ecosistema Python
Parte del fascino di Mojo sta nel fatto che non ti obbliga a buttare via ciò che già possiedi : la sua compatibilità con l'ecosistema Python ti permette di continuare a utilizzare librerie come NumPy, Pandas o Matplotlib, adottando al contempo strutture e tipi più efficienti quando lo ritieni opportuno.
In pratica, questa strategia "Python++" semplifica la curva di adozione: si mantiene il proprio codice sorgente , si spostano le parti più critiche su Mojo e si sfruttano il compilatore e MLIR per ottimizzare le prestazioni senza abbandonare la sintassi conosciuta.
Modulare: un runtime per unificare PyTorch e TensorFlow
Oltre al linguaggio, Modular ha introdotto un framework/runtime universale in grado di eseguire modelli PyTorch e TensorFlow senza richiedere l'installazione di entrambi gli stack. Secondo queste fonti, la sua architettura può accelerare l'esecuzione di TensorFlow fino a 3 volte e quella di PyTorch fino a 2,5 volte , integrando al contempo strumenti di quantizzazione e contribuendo così alla scalabilità dell'IA.
L'obiettivo è evitare l'inferno dei "tre livelli" (Python → C/C++ → hardware specifico) con un singolo livello di programmazione e un backend che comunichi con qualsiasi hardware e sfrutti al meglio ogni piattaforma senza dover riscrivere il modello ogni due giorni.
Quantizzazione: riduzione delle dimensioni senza sacrificare la precisione
Quantizzare i modelli è come un MP3 per le reti neurali: si riduce la precisione in determinati pesi/strati e, in cambio, si riducono le dimensioni e si velocizza l'inferenza. La perdita di precisione è solitamente minima (ad esempio, passando dal 94% al 91% in un classificatore) e il guadagno in termini di implementazione e velocità compensa ampiamente.
Questo approccio è fondamentale per portare i modelli sui dispositivi locali nel rispetto della privacy. Infatti, stack come Core ML e acceleratori come le NPU di Apple (tramite MPS/Accelerate) spingono verso modelli compressi che si adattano e funzionano senza problemi su un iPhone o un Mac senza inviare dati al cloud.
Da Swift per TensorFlow a Mojo: il viaggio di Lattner
Il percorso che ha portato a questo punto non è casuale. Dopo la sua esperienza in Apple (LLVM, Clang, Swift ), Chris Lattner ha lavorato presso Tesla e Google Brain, dove ha guidato lo sviluppo di Swift per TensorFlow . Quel tentativo di combinare un linguaggio moderno con l'apprendimento automatico è stato accantonato, ma ha fornito insegnamenti che ora si sono concretizzati in MLIR e nella progettazione di Mojo.
Prima di Modular, Lattner si è cimentato anche nel mondo RISC-V (SciFive), il che si allinea con l'idea che il futuro dell'IA coinvolga molti tipi di hardware e che abbiamo bisogno di compilatori e runtime in grado di adattarsi rapidamente a tutti.
Stato del progetto, supporto e adozione
Mojo è stato lanciato nel 2023 e, sebbene il linguaggio si stia evolvendo rapidamente, è ancora in una fase di maturazione . La sua libreria standard è stata resa pubblica nel febbraio 2025, ma il compilatore rimane chiuso . In termini di popolarità (indice TIOBE), Mojo si posiziona al di sotto della top 50, il che è prevedibile per un linguaggio che ha solo due anni.
Nella sezione "chi è chi", è stato menzionato il supporto di Amazon, AMD, NVIDIA e Inworld . Ciononostante, per competere con Python, avrà bisogno di una community, documentazione, pacchetti e casi di successo in produzione che possano fungere da punto di riferimento per gli altri.
Sfide: comunità, riflessione e caratteristiche dinamiche
Oltre alle prestazioni, Python vince in termini di comunità, risorse ed ecosistema . Mojo dovrà colmare le lacune nelle aree in cui Python eccelle, come alcuni meccanismi di riflessione o i modelli dinamici ampiamente utilizzati. Dovrà inoltre continuare a perfezionare la sua usabilità per rendere la transizione da Python completamente fluida.
Dal punto di vista tecnico, la promessa di " compilare per tutto " sembra fantastica, ma ogni backend (CUDA, ROCm, MPS, TPU, FPGA...) ha le sue peculiarità. Mantenere funzionalità e prestazioni coerenti su tutti in fase di esecuzione è una maratona, non uno sprint.
Mojo e GPU: oltre NVIDIA
Uno dei punti di forza di Mojo e MLIR è la loro capacità di supportare GPU sia di NVIDIA che di AMD , non solo dell'ecosistema CUDA. Se questo supporto rimarrà aggiornato e competitivo, molte aziende comprenderanno il vantaggio strategico di non essere vincolate a un singolo fornitore.
Allo stesso tempo, il mondo Apple (con MPS ) e altri acceleratori specializzati (NPU, FPGA ) richiedono percorsi di compilazione e librerie appropriate. La promessa di "scrivere una volta, eseguire velocemente ovunque" è ambiziosa e, se realizzata correttamente, rappresenterebbe una svolta epocale.
Dibattito: Nuovo linguaggio o “Python++”?
Nei forum tecnici si discute se Mojo sia "un'altra variante di Python" o un nuovo linguaggio che condivide solo la sintassi. Per l'uso quotidiano, l'aspetto fondamentale è la possibilità di riutilizzare codice e librerie, scrivendo al contempo componenti performanti con tipi e strutture più ricchi.
Questa dualità, combinata con il moderno compilatore MLIR, è ciò che permette a "hello world" di essere di facile utilizzo, consentendo al contempo ai kernel di calcolo di avvicinarsi o addirittura superare le prestazioni di C/C++ in scenari vettoriali.
Risorse, comunità e apprendimento
Se stai muovendo i primi passi nel mondo dell'IA, le comunità di apprendimento aperte sono di inestimabile valore. Questi spazi, pensati sia per studenti che per insegnanti, offrono l'opportunità di porre domande, condividere risorse e progredire dalle basi alle tecniche più avanzate. Sono luoghi fantastici per esercitarsi, confrontare approcci e ottenere risposte concrete.
Anche l'ecosistema di divulgazione è di grande aiuto: dai riepiloghi di lancio di Mojo a cura di esperti come Jeremy Howard, ai corsi Python gratuiti su piattaforme video che permettono di iniziare a programmare senza spendere nulla. Più forte sarà la community attorno a Mojo, più facile sarà per aziende e sviluppatori adottarlo.
Note pratiche e dettagli interessanti
Anche i piccoli dettagli che migliorano la qualità della vita fanno la differenza: i file .mojo , il supporto per fn / def , l'esecuzione diretta con il comando mojo o l'intenzione esplicita di offrire binari facili da distribuire . Sono cose banali, ma quando si tratta di progetti di grandi dimensioni, fanno tutta la differenza.
Allo stesso tempo, è necessario riconoscere l'influenza di Rust e Swift sulla progettazione dei tipi, sulla sicurezza della memoria e sulle astrazioni a costo zero . Non è un caso: Lattner proviene dalla creazione di Swift e dall'esperienza come pilota di LLVM/Clang; questa eredità è evidente nella progettazione del compilatore.
Dal laboratorio alla produzione: cosa aspettarsi
Se intendete provare Mojo oggi, ha senso utilizzarlo in moduli ad alto impatto (kernel di calcolo, trasformazioni intensive o cicli stretti). Mantenete l'orchestrazione e gli strumenti in Python e migrate i componenti più richiesti a Mojo per misurare i benefici reali nelle vostre metriche.
Secondo i report analizzati, le attività di tipo Mandelbrot o i kernel SIMD hanno ottenuto enormi accelerazioni . Nelle pipeline reali, con I/O, preelaborazione e librerie di terze parti, si noteranno miglioramenti significativi, sebbene più modesti e dipendenti dal collo di bottiglia dominante.
Livelli unificati: addio al “Frankenstack”
Una delle promesse principali dello stack modulare è l'unificazione dei livelli: invece di un insieme frammentato di Python + C/C++ + backend specifici, offre un unico linguaggio per tutti e tre i livelli e un runtime che interagisce con l'hardware . Meno "collanti", meno incompatibilità e meno manutenzione preventiva.
Se questa visione si concretizzerà, i processi di training e inferenza potranno passare da NVIDIA, AMD, Apple Silicon, TPU o NPU senza richiedere una riprogrammazione completa del progetto. E questa, più che un dettaglio tecnico, è una strategia aziendale : la libertà di scegliere l'hardware in base a costi, disponibilità o efficienza energetica.
Una nota sui modelli vocali e sulla trascrizione
Nelle implementazioni reali, quando si effettua il porting di modelli come Whisper (trascrizione) da Python a percorsi nativi o altre API (MPS/Accelerate), sorgono incompatibilità: alcune istruzioni esistono in CUDA ma non in MPS, o viceversa. È qui che un backend unificato e un compilatore con MLIR possono evitare molti grattacapi.
Senza questo elemento di coesione comune, si finisce per avere ramificazioni di codice e porting manuali che rallentano l'evoluzione del progetto. Con esso, la promessa è di scrivere una volta e ottenere un routing efficiente su ogni piattaforma supportata.
Contesto “meta”: sensibilizzazione, sponsorizzazioni e comunità tecnologica
Parte del materiale che alimenta questo dibattito proviene da podcast e blog tecnici che combinano contenuti educativi con sponsorizzazioni e community (persino merchandising). Al di là degli aneddoti (corsi, app, Twitch, musica di sottofondo, supporto da parte di reti di podcast...), ciò che è interessante è che il dibattito tecnico si è esteso oltre la sua nicchia e sta trovando risonanza presso un pubblico molto più ampio.
Questo rumore è positivo: porta con sé domande stimolanti, casi d'uso concreti ed esperienze con diverse tipologie di hardware. Ampliare la discussione verso MLIR e Mojo accelera l'individuazione dei bug, la creazione di guide alla migrazione e la realizzazione di soluzioni che tutti possiamo riutilizzare.
Il quadro generale è chiaro: Python rimarrà la porta d'accesso all'IA, ma esiste già un'alternativa pragmatica quando le prestazioni sono fondamentali. Mojo non mira a eliminare Python, bensì a potenziarlo con un compilatore moderno , una vera parallelizzazione e un livello runtime in grado di comprendere sia gli acceleratori attuali che quelli futuri. Se lavorate nel campo del machine learning/deep learning e il tempo/costo per inferenza o epoca di addestramento è importante, vale la pena provarlo con i vostri dati e hardware.