Porta il tuo modello
Incolla un id di modello HuggingFace e FabricLoom scarica il modello. Al termine del download, ogni cartuccia installata che sa usarlo lo prende in carico, che si tratti di embedding, trascrizione, visione o generazione. Scegli il runtime (MLX di Apple, llama.cpp o Candle), la dimensione e la quantizzazione.
Un modello da 0,5B che entra in poche centinaia di megabyte funziona, e funziona anche un modello da 70B che richiede l’intera GPU. La superficie è la stessa, compresi il click destro e il menu Transmute. Cambiano solo la velocità e la qualità della risposta.
Questa pagina copre il lato rivolto all’utente della gestione dei modelli: model spec, backend supportati, rilevazione della famiglia di modelli, dove vivono i modelli su disco, generazione strutturata e cosa permette di tarare LlmGenerationRequest.
Per il lato sviluppatore di cartucce (dichiarare un cap LLM, costruire una LlmGenerationRequest, fare il parsing dei LlmStreamMessage), vedi il Riferimento degli SDK per cartucce.
Model spec
Un modello è referenziato da una stringa di model spec. La forma più comune è HuggingFace:
hf:OWNER/REPO
hf:OWNER/REPO?include=*PATTERN*
Esempi:
hf:meta-llama/Llama-3.2-1B-Instruct
hf:MaziyarPanahi/Mistral-7B-Instruct-v0.3-GGUF?include=*Q8_0*
hf:mlx-community/Llama-3.2-1B-Instruct-4bit
Il filtro include= viene confrontato con i nomi dei file nel repo ed è utile per scegliere una specifica quantizzazione da una release GGUF multi-file. Senza filtro, la cartuccia sceglie un default, di solito la quantizzazione più grande disponibile che rientra nelle preferenze del runtime.
Le cartucce inviano la stringa di model spec anche in LlmGenerationRequest.model_spec, e la regola di dispatch instrada su di essa. Quando due cartucce servono entrambe cap:llm-inference;..., vengono classificate in base a quanto specificamente corrispondono allo spec. Una cartuccia consapevole di Mistral che nomina la famiglia nei suoi tag batte una generica per i modelli Mistral.
Backend
Oggi tre runtime sono di prima classe:
| Backend | Origine | Modelli |
|---|---|---|
GGUF (binding llama.cpp) |
BACKEND_GGUF |
Modelli GGUF quantizzati: Llama, Mistral, Qwen, Phi e i molti repo *-GGUF su HuggingFace |
| MLX | BACKEND_MLX |
MLX di Apple, nativo Apple Silicon, modelli mlx-community/* |
| Candle | BACKEND_CANDLE |
Inferenza Rust-native per famiglie di modelli selezionate |
Una cartuccia dichiara quale backend implementa. L’SDK fornisce un helper backend_for_model_spec(model_spec) che classifica uno spec in uno di questi, e le cartucce che incapsulano un solo backend lo usano per dichiarare solo i model spec che possono gestire.
Le costanti cap URN standard dell’SDK delle cartucce corrispondono a questi backend:
CAP_LLM_INFERENCE_GGUFCAP_LLM_INFERENCE_MLXCAP_LLM_INFERENCE_CANDLECAP_LLM_INFERENCE_CONSTRAINED: generazione vincolata (JSON Schema, regex, grammar, tool-call), instradata al backend che supporta il vincolo
Quando chiami un cap LLM generico, il dispatch sceglie il backend in base al model spec. Quando chiami direttamente un cap specifico per backend, hai scelto tu il runtime.
Famiglie di modelli
Famiglie di LLM diverse usano formati di prompt diversi. Mistral usa [INST] ... [/INST], Llama 3 usa turni basati su header (<|start_header_id|>user<|end_header_id|>...), Phi usa <|user|> ... <|end|> e Qwen usa lo stile ChatML <|im_start|>user ... <|im_end|>. Un modello che riceve i marcatori di turno sbagliati non fallisce in modo visibile: genera conversazioni multi-turno plausibili ma allucinate.
MachineFabric gestisce questo automaticamente. Quando un cap di generazione viene dispatchato, l’host ispeziona la stringa di model spec, rileva la famiglia dal percorso (parole chiave mistral, llama, phi, qwen) e sceglie l’adapter corrispondente. Un adapter è un piccolo pezzo di codice che conosce il formato di prompt della famiglia, le sue stop sequence per i confini di conversazione e come fare il parsing della sua risposta.
Le famiglie riconosciute sono:
| Famiglia | Riconosciuta da | L’adapter gestisce |
|---|---|---|
| Mistral | mistral nel percorso |
Formattazione [INST]/[/INST]; stop su |
| Llama 3 | llama nel percorso |
Turni basati su header; stop su <|start_header_id|>, |
| Phi | phi nel percorso |
Token speciali Phi-3; stop su <|user|>, |
| Qwen | qwen nel percorso |
Formato ChatML; stop su <|im_start|>, |
| (fallback) | nessuna delle precedenti | Formattazione generica User:/Assistant: |
Una nuova famiglia si aggiunge inserendo la rilevazione nell’host, definendo l’adapter e aggiungendo le voci media URN corrispondenti. Le cartucce che incapsulano un modello non devono sapere nulla di tutto questo, perché l’host seleziona l’adapter prima che la cartuccia veda la richiesta.
Parametri di generazione
Una richiesta di generazione è un payload tipizzato (LlmGenerationRequest, trasportato come media:fmt=json;llm-generation-request;record). I campi che una cartuccia può leggere:
| Campo | Scopo |
|---|---|
prompt |
Il testo di input rivolto all’utente. Obbligatorio. |
model_spec |
La stringa di model spec (id HuggingFace con filtro include opzionale). Obbligatorio. |
request_type |
Generate, |
system_prompt |
System prompt opzionale anteposto al prompt utente. |
max_tokens, |
I soliti controlli di sampling. |
top_k, |
Sampling truncation/nucleus. |
seed |
Seed intero opzionale per sampling riproducibile. |
repeat_penalty |
Default 1.1. Penalizza i token generati di recente e interrompe i loop di ripetizione. |
stop_sequences |
Stringhe di stop aggiuntive fornite dal chiamante, unite a quelle dell’adapter di famiglia. |
chat_template |
Override opzionale del chat template del modello. |
max_context_length, |
Parametri di tuning del runtime. |
rope_freq_base, |
Scaling RoPE per modelli a contesto esteso. |
grammar, |
Vedi Generazione strutturata. |
hf_token |
Token HuggingFace se il modello richiede autenticazione al momento del download. |
I default vengono applicati da LlmGenerationRequest::with_defaults() nell’SDK, quindi i chiamanti impostano solo ciò che vogliono sovrascrivere.
Risposte in streaming
Le risposte di generazione arrivano come stream di valori LlmStreamMessage, uno per riga di media:fmt=ndjson;llm-text-stream:
| Messaggio | Trasporta |
|---|---|
Token |
Un singolo token generato (o frammento di testo), per la visualizzazione live |
Status |
Info di progresso (preparing, generating, finalising) |
Complete |
Marker di fine generazione con statistiche finali (token generati, tempo impiegato) |
ToolRequest |
Output di tool-call vincolato: il modello ha prodotto un’invocazione di tool strutturata |
Error |
Un fallimento durante la generazione; lo stream termina dopo questo |
Le cartucce che consumano lo stream possono renderizzare i token live, contare il throughput e passare le tool-call a ciò che orchestra la conversazione. L’interfaccia di FabricLoom usa lo stesso stream: l’avanzamento live mostrato durante una generazione viene dai messaggi Token e Status.
Generazione strutturata
Per output strutturati la richiesta può trasportare un vincolo:
| Vincolo | Trasporta |
|---|---|
JsonSchema |
Un JSON Schema che descrive la forma di output attesa |
Regex |
Un’espressione regolare a cui l’output deve corrispondere |
Grammar |
Una grammatica formale (in stile Lark) a cui l’output deve conformarsi |
ToolCall |
Una lista di ToolDefinition che il modello può invocare |
La generazione vincolata è dispatchata attraverso CAP_LLM_INFERENCE_CONSTRAINED. Il runtime applica il vincolo al momento del sampling, quindi il modello non può generare output che lo violi. Gli output strutturati (JSON, tool-call, classificazioni) tornano perciò ben formati senza un ciclo di parsing e nuovo tentativo.
Gli helper URN standard nell’SDK pre-costruiscono i cap URN per i pattern strutturati comuni:
generate_json_urn(lang_code): genera un record JSON conforme a uno schemamake_decision_urn(lang_code): sceglie una di un insieme di opzionimake_multiple_decisions_urn(lang_code): sceglie un sottoinsieme di un insieme di opzionillm_summarization_urn(lang_code): riassume testollm_codegeneration_urn(lang_code): genera codice
Il catalogo URN completo è in capdag.standard.caps.
Embedding e visione
Gli embedding e la descrizione di immagini seguono lo stesso schema di cap URN tipizzati e payload tipizzati:
| Costante cap | Cosa fa |
|---|---|
CAP_GENERATE_EMBEDDINGS |
Produce un embedding vettoriale da testo o altro input |
CAP_EMBEDDINGS_DIMENSIONS |
Riporta le dimensioni dell’embedding per un modello |
CAP_DESCRIBE_IMAGE |
Genera una descrizione testuale di un’immagine |
Gli embedding sono instradati per model spec come la generazione: incolla un id di modello di embedding HuggingFace e qualsiasi cartuccia che sa eseguirlo lo prende in carico.
Dove vivono i modelli
I modelli scaricati sono messi in cache su disco, così non vengono scaricati di nuovo. Il layout della directory è un dettaglio di implementazione dell’host e può cambiare. FabricLoom tiene traccia di ogni modello scaricato con un cap cap:model-status e mostra nella sua interfaccia viste di installazione, rimozione e uso del disco. L’SDK delle cartucce espone il ciclo di vita del modello attraverso questi builder URN standard:
model_download_urn(): scarica un modello per specmodel_list_urn(): elenca i modelli installatimodel_status_urn(): interroga lo stato di installazione di un modellomodel_contents_urn(): elenca i file in un modello installatomodel_availability_urn(): verifica se uno spec si risolve in un modello scaricabilemodel_path_urn(): ottiene il percorso su disco di un modello installato
Le cartucce che hanno bisogno di un file di modello dovrebbero risolverlo con model_path_urn() invece di scrivere i percorsi nel codice. L’host risolve il percorso solo dopo che il modello è stato scaricato per intero, quindi le cartucce non devono gestire i download parziali.
Mescolare locale e remoto
Le cartucce attualmente girano in processi isolati in una sandbox rigorosa, senza accesso di rete di default. Il protocollo non esclude una cartuccia che fa da proxy verso un servizio cloud. Una cartuccia che dichiara entitlement di rete e viene revisionata per l’inclusione può instradare le richieste a un modello remoto con gli stessi media URN di ogni altra cartuccia. Capacità locali e remote possono allora essere mescolate nella stessa pipeline, e la regola di dispatch, il grafo del planner e l’avanzamento live si comportano allo stesso modo. Cambia solo il luogo in cui l’inferenza viene eseguita.
Il default oggi è locale. Il proxying di rete è opt-in.