In questa sezione

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_GGUF
  • CAP_LLM_INFERENCE_MLX
  • CAP_LLM_INFERENCE_CANDLE
  • CAP_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 [INST], <<SYS>>
Llama 3 llama nel percorso Turni basati su header; stop su <|start_header_id|>, <|eot_id|>
Phi phi nel percorso Token speciali Phi-3; stop su <|user|>, <|end|>
Qwen qwen nel percorso Formato ChatML; stop su <|im_start|>, <|im_end|>
(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, GetVocab o GetInfo. Default Generate.
system_prompt System prompt opzionale anteposto al prompt utente.
max_tokens, temperature I soliti controlli di sampling.
top_k, top_p, min_p 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, batch_size Parametri di tuning del runtime.
rope_freq_base, rope_freq_scale Scaling RoPE per modelli a contesto esteso.
grammar, json_schema, constraint 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 schema
  • make_decision_urn(lang_code): sceglie una di un insieme di opzioni
  • make_multiple_decisions_urn(lang_code): sceglie un sottoinsieme di un insieme di opzioni
  • llm_summarization_urn(lang_code): riassume testo
  • llm_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 spec
  • model_list_urn(): elenca i modelli installati
  • model_status_urn(): interroga lo stato di installazione di un modello
  • model_contents_urn(): elenca i file in un modello installato
  • model_availability_urn(): verifica se uno spec si risolve in un modello scaricabile
  • model_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.