Ingegneria
Quali modelli girano davvero su MLX
Come capire, prima di scaricare otto gigabyte, se un modello su Hugging Face si caricherà su Apple Silicon: il formato, l'architettura, la quantizzazione, e le quattro trappole facili da mancare.
Aggiornato 2026-09-12Misurato 2026-09-07
La pagina di un modello su Hugging Face non dice se quella cosa girerà sul tuo Mac. Lo scopri dopo il download, da un errore che nomina un campo di un file che non hai mai aperto.
Tutto quello che segue si controlla dall'elenco dei file di un repository e dal suo
config.json, in circa due richieste. Vale per MLX in generale e non solo per Runlix: le trappole
stanno nel formato e nelle configurazioni dei modelli, e prendono qualunque runtime le legga.
Prima domanda: c'è un file safetensors?
MLX carica safetensors. Non GGUF, non PyTorch .bin, non ONNX, non GGML.
È la delusione più comune, e il motivo è che quasi tutto il materiale su «fallo girare in locale» non parla affatto di MLX: parla di llama.cpp, il cui contenitore GGUF non è intercambiabile coi safetensors. GGUF è il contenitore di llama.cpp: porta con sé i propri schemi di quantizzazione e i propri metadati, e leggerlo significa implementare quel contenitore. Un modello pubblicato solo come GGUF non gira su MLX, e nessuna configurazione lo cambia.
La scorciatoia pratica: cerca una versione mlx-community del modello. Quell'organizzazione
ripubblica i modelli convertiti in safetensors MLX, di solito in più quantizzazioni, e se ne
esiste una è quasi sempre la cosa giusta da scaricare.
Fuori anche un repository che ha solo pytorch_model.bin, il che sorprende perché i pesi «ci
sono». Un esempio vero: BAAI/bge-m3 pubblica esclusivamente pesi PyTorch, quindi non si carica —
e il motivo è il formato, non l'architettura, che invece è supportata.
Seconda domanda: cosa dice model_type?
Apri il config.json nel repository — Hugging Face lo mostra nel browser — e cerca model_type.
Quella stringa decide quale implementazione legge i pesi, e se nessuna la implementa il modello
non si carica.
Due cose su quella stringa vanno sapute, perché portano entrambe a conclusioni sbagliate.
Gli alias esistono. Per l'implementazione, mistral è un altro nome di llama:
l'architettura ha la stessa forma, quindi un modello Mistral gira ovunque giri llama, anche se
dal nome non si direbbe. La libreria di MLX tiene una tabella di rimappatura apposta, ed è quella
da consultare invece di un elenco scritto a mano da qualcuno.
I modelli di visione si nascondono dietro nomi da modello testuale. gemma3 e qwen2_5_vl
hanno un model_type che somiglia a quello di un modello di solo testo, e guardare prima
l'architettura fa passare un modello di visione. I segnali affidabili stanno altrove nel
repository: un preprocessor_config.json, un blocco vision_config dentro config.json, o un
nome che contiene _vl, vision, llava o paligemma. Controllali prima di guardare la
famiglia.
Terza domanda: com'è quantizzato?
I modelli MLX quantizzati portano un blocco quantization nel config.json col numero di bit e
la dimensione del gruppo. Quattro bit è il caso comune e funziona bene; otto costa più memoria ed
è più vicino all'originale.
La trappola qui è la quantizzazione per tensore. Certi pubblicatori quantizzano tensori diversi a precisioni diverse e lo registrano come una mappa dentro la configurazione invece che come un'impostazione sola. Un runtime che applica una quantizzazione a tutto il modello leggerà quei pesi col numero di bit sbagliato — e questo non fallisce rumorosamente. Produce numeri sbagliati in un modo che continua a somigliare a del testo.
Un esempio vero che ci inciampa: Qwen3.8-27B-Uncensored-OptiQ-4bit. Il nome dice 4 bit; la
configurazione dice altro per alcuni tensori.
Quarta domanda: la configurazione dichiara qualcosa di esotico?
Tre campi causano errori silenziosi invece di un fallimento pulito, ed è per questo che un runtime prudente li rifiuta invece di indovinare.
rope_scaling descrive come l'informazione di posizione viene stirata per arrivare a un
contesto più lungo. default, llama3 e yarn sono gli schemi comunemente implementati.
Qualcos'altro significa che le posizioni verranno calcolate diversamente da come il modello è
stato addestrato, e l'uscita sarà plausibile e peggiorata invece che rotta in modo evidente.
Su YaRN vale la pena sapere una cosa in particolare: quando dichiara mscale_all_dim, scala
anche l'attenzione oltre alle frequenze, non solo le frequenze. Mancarlo non dà un errore —
dà logit tutti fuori scala dello stesso fattore, quindi la classifica continua a sembrare
sensata mentre i valori non lo sono.
sliding_window limita quanto indietro arriva l'attenzione. E qui c'è la trappola, che è una
bella: Qwen2.5 la dichiara a 131072 e poi mette use_sliding_window: false. Un controllo che
legge solo il primo campo rifiuta un modello che va benissimo. Vanno letti entrambi.
layer_types compare sui modelli che mescolano tipi di attenzione diversi fra i livelli.
Qualcosa di diverso da full attention su ogni livello significa che il modello si aspetta un
comportamento che un'implementazione semplice non fornisce.
Quinta domanda: ci sta?
MLX gira sulla GPU, e su Apple Silicon la GPU condivide la memoria con tutto il resto. Il tetto non è il numero di RAM scritto sulla scatola: è il working set che Metal raccomanda, che è più basso. Su una macchina da 24 GB è tornato 23347 MB — ed è il tetto per tutto, non solo per i pesi.
Una stima grossolana che regge: i pesi su disco sono vicini alla memoria che occupano, e un prompt lungo costa parecchio in più sopra. Misurato su una llama piccola, il picco con un prompt da 4096 token era 1,68× i pesi. Raddoppiare la dimensione dei pesi è una cifra di pianificazione prudente.
Quindi un modello a 4 bit i cui file fanno 8 GB ne vuole intorno a 16 disponibili per stare comodo coi prompt lunghi — il che su una macchina da 16 GB significa che è l'unica cosa che stai facendo girare.
Leggere la scheda di un modello senza farsi ingannare
Le schede dei modelli le scrivono persone contente del proprio modello, il che è giusto, e non sono scritte per dirti se si caricherà. Tre abitudini aiutano.
Ignora il numero di parametri nel nome e guarda le dimensioni dei file. «7B» dice qualcosa dell'architettura, non di quello che scaricherai. Lo stesso modello da 7B esiste come 15 GB di pesi a 16 bit, 8 GB a 8 bit e 4 GB a 4 bit, e il nome è identico in tutti e tre i casi. L'elenco dei file è il numero onesto.
Ignora del tutto le tabelle dei benchmark, per questo scopo. Non dicono niente sul formato, e un modello che va forte e non si carica sulla tua macchina va a zero.
Guarda cosa contiene davvero il repository invece di cosa descrive la scheda. Spesso una scheda descrive il modello originale mentre il repository contiene una conversione, o il contrario. I file non hanno opinioni.
Quando la risposta è «non ancora»
Fra «gira» e «non gira» c'è una risposta di mezzo, e vale la pena capirla perché è dove finiscono parecchi modelli.
La libreria di MLX implementa ben più di cento architetture. Un runtime qualunque ne implementa meno — Runlix ne implementa sei — e la differenza non è un difetto da nessuna delle due parti: un'architettura tradotta va verificata contro un riferimento prima di potersene fidare, e la verifica è la parte che costa tempo.
Quindi gli elenchi da controllare sono due invece di uno: le architetture del runtime, e quelle della libreria. Una famiglia che sta nel secondo e non nel primo è non ancora — conosciuta, traducibile, in attesa di essere verificata. Una famiglia che non sta in nessuno dei due è un altro discorso: oggi non la esegue nessuno su MLX, e aspettare un runtime non lo cambia.
Cosa niente di tutto questo ti dice
Tutto quanto sopra riguarda se i pesi si caricheranno e produrranno numeri. Non dice niente su quanto il modello sia buono, se parli bene la tua lingua, se la sua licenza permetta ciò che hai in mente, o se la quantizzazione gli abbia tolto qualcosa che conta per il tuo compito.
La quantizzazione a quattro bit in particolare non è gratis. Di solito è uno scambio conveniente, e sui modelli piccoli a volte no — più il modello è piccolo, più ogni bit stava facendo qualcosa. Se un modello a 4 bit ti delude, provare la versione a 8 bit della stessa cosa è un esperimento più economico che cambiare modello.
La versione corta
Prima di scaricare, controlla cinque cose in quest'ordine:
- ci sono i safetensors — altrimenti fermati;
- non è un modello di visione — guarda prima
preprocessor_config.jsonevision_config, perché il nome non te lo dirà; model_typeè implementato — ricordando che gli alias esistono e chemistralèllama;- la quantizzazione è un'impostazione sola, non una mappa per tensore;
rope_scaling,sliding_windowelayer_typessono ordinari — e leggi entrambi i campi della finestra scorrevole.
Perché «non lo so» è una risposta vera
Ognuno di questi controlli può non arrivare a una conclusione: il repository può non rispondere,
o può non avere affatto un config.json. La tentazione è indovinare, perché un verdetto sembra
più utile di un'alzata di spalle.
Non lo è. Un runtime che indovina quando non può sapere prima o poi indovinerà male, con sicurezza, e tu passerai la sessione di indagine sull'ipotesi sbagliata. Non sapere vale la pena dirlo ad alta voce.
Runlix fa questi controlli al posto tuo, sulla riga, prima del download — con la ragione scritta accanto al verdetto, compreso quando la ragione è che non è riuscito a saperlo. Ma il punto sono i controlli, non lo strumento: sono cinque domande su un file che chiunque può leggere, e saperle vale più di qualunque applicazione che le risponda al posto tuo.