Source: https://aiprimetech.io/it/blog/lemonade-by-amd-a-fast-and-open-source-local-llm-server-using-gpu-and-/ Giu 14, 2026 · 5 min · Ingegneria # Lemonade di AMD: un server LLM locale veloce e open source che usa la GPU ... A Di [AI Prime Tech](https://aiprimetech.io/it/) · Con l'assistenza dell'AI ## Lemonade di AMD: un server LLM locale veloce e open source che usa GPU e NPU Un server LLM locale pensato per un uso pratico smette di essere “locale” nel momento in cui impiega 18 secondi per rispondere a un prompt di 20 token. Ho visto ripetutamente questo schema sui portatili degli sviluppatori: il modello tecnicamente funziona, l'utilizzo della CPU resta fisso al 700%, le ventole accelerano e il primo token arriva quando l'utente ha già perso il filo. Questo è il problema ingegneristico che Lemonade cerca di risolvere: far sì che l'inferenza locale si comporti come un vero servizio, non come uno script dimostrativo. Lemonade di AMD è un server LLM locale open source progettato per eseguire modelli linguistici sull'hardware client, in particolare sui sistemi AMD con accelerazione GPU e NPU Ryzen AI. L'aspetto interessante non è solo “eseguire un modello in locale”. Abbiamo già diversi modi per farlo. L'aspetto interessante è l'architettura del server: esporre i modelli locali tramite un'API, instradare l'inferenza attraverso gli acceleratori disponibili e renderla utilizzabile dal normale codice applicativo. Per gli ingegneri che sviluppano copiloti locali, assistenti privati per documenti, sandbox per agenti o flussi di lavoro di inferenza offline, questa è l'astrazione giusta. Non vuoi che ogni applicazione debba sapere come caricare un modello, quantizzare i pesi, scegliere i provider di esecuzione, bloccare la memoria, trasmettere i token in streaming e gestire le sessioni. Vuoi un servizio di inferenza locale. ## A cosa serve davvero Lemonade A grandi linee, Lemonade è un server di modelli locale. Si colloca tra la tua applicazione e l'hardware. Invece di incorporare la logica di inferenza direttamente nella tua app, esegui un demone locale: ``` lemonade-server serve ``` La tua applicazione comunica quindi con il demone tramite HTTP, spesso attraverso un'API di completamento chat in stile OpenAI: ``` from openai import OpenAI client = OpenAI( base_url="http://localhost:8000/api/v1", api_key="not-needed-for-local" ) response = client.chat.completions.create( model="llama-3.1-8b-instruct", messages=[ {"role": "system", "content": "You are a concise coding assistant."}, {"role": "user", "content": "Write a Python function to chunk text by tokens."} ], temperature=0.2, stream=True, ) for chunk in response: delta = chunk.choices[0].delta.content if delta: print(delta, end="", flush=True) ``` La struttura dell'API conta. Se il tuo backend supporta già GPT-5.5, Claude Sonnet 4.6, Gemini 3 o un endpoint per modelli aperti, spesso puoi indirizzare la stessa astrazione client a Lemonade per l'esecuzione locale. Questo ti permette di testare l'instradamento dei modelli, le funzionalità sensibili alla privacy e i flussi di lavoro offline senza riscrivere la tua app attorno a un nuovo SDK. In pratica, considero un server LLM locale un componente dell'infrastruttura: ``` App / IDE / Agent Runtime | | HTTP streaming chat API v Lemonade local server | | model loader + scheduler v Execution backend | | GPU / NPU / CPU fallback v AMD client hardware ``` È questa netta separazione a renderlo utilizzabile nei sistemi reali. ## Perché GPU e NPU sono entrambe importanti La maggior parte degli ingegneri comprende già perché l'accelerazione GPU sia importante per l'inferenza LLM: le moltiplicazioni di matrici dominano il tempo di esecuzione e le GPU sono progettate per il calcolo parallelo. Il ruolo della NPU è più recente ed è più facile fraintenderlo. Una NPU non è “una GPU più piccola”. È un acceleratore specializzato, ottimizzato per le operazioni delle reti neurali entro rigidi vincoli energetici e termici. Su un portatile, questo conta. Lo stack di inferenza locale migliore non è sempre quello che raggiunge il picco più alto di token al secondo in un benchmark di 30 secondi. Spesso è quello che rimane reattivo mentre l'utente tiene aperti Slack, un browser, VS Code e Docker. Un modello mentale utile: - GPU: più adatta a modelli più grandi, throughput più elevato e calcolo parallelo più intenso. - NPU: interessante per modelli a basso consumo, sempre attivi, più piccoli o ottimizzati. - CPU: soluzione di ripiego affidabile, ma solitamente con una latenza poco adatta all'uso interattivo degli LLM. - Sistemi ibridi: utili per instradare il lavoro in base alle dimensioni del modello, alla quantizzazione e alla disponibilità. Ad esempio, un assistente locale potrebbe usare: ``` { "routes": { "autocomplete": { "model": "small-code-model", "device": "npu", "max_tokens": 64 }, "chat": { "model": "llama-3.1-8b-instruct-q4", "device": "gpu", "max_tokens": 1024 }, "summarization": { "model": "compact-instruct", "device": "auto", "max_tokens": 512 } } } ``` È questo l'approccio che preferisco: non scegliere un unico acceleratore in modo dogmatico. Scegli la destinazione di esecuzione giusta per ogni carico di lavoro. ## Come si colloca Lemonade tra i server LLM locali Oggi esistono diverse soluzioni mature per l'inferenza locale. L'approccio distintivo di Lemonade è l'accelerazione locale pensata innanzitutto per AMD, in particolare per i sistemi in cui GPU e NPU fanno entrambe parte della piattaforma client. | Strumento | Impiego ideale | Stile API | Hardware di riferimento | Compromesso tipico | Lemonade | Serving locale su GPU/NPU AMD | HTTP locale / utilizzo simile a OpenAI | Hardware client AMD | Ecosistema più recente rispetto ai server storici | Ollama | Gestione semplice dei modelli locali | API REST | Ampio supporto per CPU/GPU | Minore controllo sull'esecuzione a basso livello | Server llama.cpp | Inferenza quantizzata portabile | Modalità REST / compatibili con OpenAI | CPU, Metal, CUDA, Vulkan e altri | La configurazione del backend può richiedere interventi manuali | vLLM | Serving ad alta capacità di elaborazione | Compatibile con OpenAI | GPU per server | Maggiori requisiti per il deployment | LM Studio | Sperimentazione locale su desktop | Interfaccia grafica + server locale | Computer di fascia consumer | Meno adatto all'automazione dell'infrastruttura Lemonade non è un sostituto diretto per qualsiasi stack di inferenza. Se servi centinaia di utenti simultanei usando GPU da datacenter, il batching continuo nello stile di vLLM è solitamente l'architettura più pertinente. Se ti serve la massima portabilità possibile su macchine di ogni tipo, llama.cpp resta difficile da battere. Lemonade diventa interessante quando la macchina di destinazione è un portatile, una workstation o un dispositivo edge AMD e ti interessa un server locale di primo livello anziché uno script Python occasionale. ## Un'architettura locale pratica Ecco uno schema che funziona bene per le applicazioni AI locali: ``` ┌──────────────────────────────┐ │ Desktop App / Backend Service │ └───────────────┬──────────────┘ │ OpenAI-compatible client v ┌──────────────────────────────┐ │ Local Model Gateway │ │ - retries │ │ - model routing │ │ - prompt templates │ │ - telemetry │ └───────────────┬──────────────┘ │ localhost HTTP v ┌──────────────────────────────┐ │ Lemonade Server │ │ - model loading │ │ - streaming responses │ │ - device selection │ │ - accelerator backend │ └───────────────┬──────────────┘ │ ┌────────┴────────┐ v v AMD GPU Ryzen AI NPU ``` Di solito aggiungo un gateway leggero anche quando il server locale espone già un'API ben progettata. Il gateway offre un contratto interno stabile e consente di passare dai modelli locali a quelli remoti. Per esempio: ``` import os from openai import OpenAI def build_llm_client(): if os.getenv("LLM_MODE") == "local": return OpenAI( base_url="http://localhost:8000/api/v1", api_key="local" ) return OpenAI( base_url=os.environ["REMOTE_LLM_BASE_URL"], api_key=os.environ["REMOTE_LLM_API_KEY"] ) client = build_llm_client() ``` In questo modo, per la logica della tua app non fa differenza se la richiesta viene inviata a Lemonade, GPT-5.5, Claude Opus 4.8, Gemini 3 o a un modello aperto ospitato. Questa flessibilità è preziosa quando valuti qualità, latenza, privacy e costi. Se il tuo team usa un provider di API multimodello come AI Prime Tech per il fallback sul cloud, mantieni il percorso locale e quello remoto dietro la stessa interfaccia. ## Scelta del modello: dimensioni ridotte battono l'intelligenza teorica L'errore più comune con i server LLM locali è scegliere un modello perché ottiene buoni risultati in una classifica, anziché perché è adatto alla macchina. Per l'inferenza locale, l'adeguatezza del modello è tutto: - Il modello quantizzato rientra nella memoria disponibile dell'acceleratore? - La lunghezza del contesto è realistica per il carico di lavoro? - Quanto tempo passa prima del primo token? - Lo streaming è fluido nelle normali condizioni termiche di un portatile? - L'app può tollerare un fallback occasionale sulla CPU? - La qualità è sufficiente per il compito? Un modello instruct da 7B o 8B quantizzato a 4 bit è spesso più utile in locale di un modello molto più grande che trasferisce continuamente dati fuori dalla memoria dell'acceleratore, si blocca o impone tagli drastici al contesto. Per le attività di programmazione, i modelli aperti derivati da Qwen, DeepSeek, Llama, MiniMax e Kimi possono tutti essere candidati ragionevoli, a seconda della licenza, del supporto dei formati e della compatibilità con il backend. Il flusso di lavoro corretto è empirico: ``` # Example benchmark flow; adapt names to installed Lemonade commands/models. lemonade-server pull llama-3.1-8b-instruct-q4 lemonade-server serve --host 127.0.0.1 --port 8000 ``` Quindi esegui un prompt ripetibile: ``` import time from openai import OpenAI client = OpenAI(base_url="http://localhost:8000/api/v1", api_key="local") prompt = "Explain how an LRU cache works, then implement one in Python." start = time.perf_counter() first_token_at = None tokens = 0 stream = client.chat.completions.create( model="llama-3.1-8b-instruct-q4", messages=[{"role": "user", "content": prompt}], stream=True, temperature=0.1, max_tokens=400, ) for chunk in stream: text = chunk.choices[0].delta.content or "" if text and first_token_at is None: first_token_at = time.perf_counter() tokens += len(text.split()) end = time.perf_counter() print({ "time_to_first_token_s": round(first_token_at - start, 3), "total_time_s": round(end - start, 3), "rough_word_rate_per_s": round(tokens / (end - start), 2) }) ``` Non è un benchmark scientificamente perfetto. È uno smoke test pratico. Ti dice quale esperienza avrà il tuo utente. ## Selezione del dispositivo e fallback Un buon server locale dovrebbe rendere la selezione del dispositivo abbastanza esplicita da consentire agli ingegneri di analizzare i malfunzionamenti. “Auto” è comodo finché un modello non passa silenziosamente dalla GPU alla CPU e la latenza aumenta di 8x. Nei deployment locali simili a quelli di produzione, preferisco una configurazione semplice e verificabile: ``` { "server": { "host": "127.0.0.1", "port": 8000 }, "models": [ { "name": "local-chat", "path": "./models/llama-3.1-8b-instruct-q4", "device": "gpu", "context_length": 8192 }, { "name": "fast-draft", "path": "./models/small-instruct-npu", "device": "npu", "context_length": 4096 } ], "fallback": { "allow_cpu": false, "on_failure": "return_error" } } ``` Le opzioni di configurazione precise di Lemonade possono variare in base alla versione, ma il principio resta valido: evita degradazioni invisibili. Se il percorso GPU non funziona, voglio che l'app lo sappia. Per le applicazioni interattive, restituire un errore chiaro è spesso meglio che far aspettare all'utente 90 secondi per una risposta dalla CPU. Un'insidia comune: i driver e le librerie di runtime contano quanto il modello. Quando l'accelerazione GPU o NPU non si attiva, il server può comunque “funzionare”, ma lentamente. Verifica sempre nei log all'avvio quale provider di esecuzione è attivo. Controlli utili all'avvio: ``` lemonade-server serve --log-level debug ``` Cerca: ``` loaded model: local-chat selected device: gpu execution provider: context length: 8192 quantization: q4 ``` Se i log non mostrano chiaramente il percorso dell'acceleratore, considera l'accelerazione ancora da verificare. ## Lo streaming non è facoltativo Per l'esperienza utente degli LLM locali, lo streaming è un requisito. Anche quando il tempo totale di completamento non cambia, lo streaming fa sembrare l'app nettamente più veloce perché l'utente vede i progressi. Il server dovrebbe supportare lo streaming dei token e il client dovrebbe gestirlo correttamente: ``` def stream_answer(client, model, messages): stream = client.chat.completions.create( model=model, messages=messages, stream=True, temperature=0.2, max_tokens=700, ) for event in stream: piece = event.choices[0].delta.content if piece: yield piece ``` In pratica, lo streaming aiuta anche nel debug. Se la latenza del primo token è elevata ma la generazione successiva è veloce, il collo di bottiglia potrebbe essere il caricamento del modello, l'elaborazione del prompt o la lunghezza del contesto. Se il primo token arriva rapidamente ma la generazione procede a rilento, potresti essere limitato dalla larghezza di banda della memoria, dalla riduzione delle prestazioni per motivi termici o dal fallback sulla CPU. Misura separatamente questi aspetti: - Tempo di avvio a freddo: dall'avvio del server al momento in cui il modello è pronto. - Tempo di elaborazione del prompt: dalla ricezione della richiesta al primo token. - Velocità di decodifica: dal primo token all'ultimo token. - Latenza end-to-end: dalla richiesta dell'applicazione alla risposta completa. - Stabilità termica: lo stesso test dopo cinque minuti di utilizzo. L'ultimo aspetto è facile da ignorare, ma causa problemi nei prodotti reali. ## Lunghezza del contesto: il moltiplicatore silenzioso della latenza Le finestre di contesto lunghe sono utili, ma hanno un costo. Un modello che supporta un contesto di 8192 token o 32768 token può comunque diventare sgradevole da usare se riempi ogni richiesta di log, documenti e cronologia della chat. Per i sistemi locali, di solito impongo limiti al contesto nel gateway: ``` MAX_PROMPT_CHARS = 18_000 def trim_context(system_prompt, history, new_user_message): packed = [ {"role": "system", "content": system_prompt}, *history[-8:], {"role": "user", "content": new_user_message}, ] total = sum(len(m["content"]) for m in packed) while total > MAX_PROMPT_CHARS and len(packed) > 2: removed = packed.pop(1) total -= len(removed["content"]) return packed ``` È un approccio rudimentale ma efficace. Una versione più evoluta usa il conteggio dei token, la compressione semantica e il recupero delle informazioni. Il punto importante è che la gestione del contesto spetta al livello applicativo, anziché alla vaga speranza che il server rimanga veloce. Se usi un modello con un contesto ampio, come Fable 5 con un contesto di 1M, in un ambiente cloud, cambiano i vincoli di progettazione. Su un sistema GPU/NPU locale, dovresti presumere che il contesto sia costoso, a meno che le tue misurazioni non dimostrino il contrario. ## Best practice per il serving locale nello stile di Lemonade ### Mantieni il server pronto Il caricamento del modello a freddo è uno dei principali fattori che compromettono l'esperienza utente. Avvia il server insieme all'app, carica subito il modello predefinito ed esponi lo stato di disponibilità separatamente dallo stato di salute del processo. ``` curl http://127.0.0.1:8000/health curl http://127.0.0.1:8000/models ``` La tua app dovrebbe distinguere tra: - il processo del server è in esecuzione - il modello è caricato - l'acceleratore è attivo - il percorso delle richieste funziona correttamente ### Fissa le versioni dei modelli Non lasciare che i modelli “latest” cambino silenziosamente all'interno di un'app desktop. Fissa i nomi dei modelli, la quantizzazione e la lunghezza del contesto prevista. ``` { "model": "llama-3.1-8b-instruct-q4", "revision": "2025-02-local-tested", "expected_device": "gpu" } ``` Anche piccole modifiche al tokenizer, al template della chat o alla quantizzazione possono cambiare il comportamento. ### Separa i test di qualità dai test di velocità Per molti flussi di lavoro, un modello locale veloce che fornisce risposte con errori sottili è peggiore di uno più lento. Preferisco mantenere due insiemi di test: ``` evals/ latency_prompts.jsonl task_quality_prompts.jsonl ``` Esempio di caso per il test di qualità: ``` { "id": "python_exception_summary_01", "messages": [ { "role": "user", "content": "Summarize this stack trace and identify the likely bug: ..." } ], "must_include": ["None", "attribute", "guard"], "must_not_include": ["database outage"] } ``` Non sostituisce una valutazione formale, ma rileva le regressioni quando cambi modello, quantizzazione o percorso del dispositivo. ### Progetta il fallback remoto L'inferenza locale fallisce per motivi ordinari: modalità di risparmio energetico del portatile, aggiornamenti dei driver, file del modello mancanti, quantizzazione non supportata, riduzione delle prestazioni per motivi termici. Se il compito è importante, prevedi un fallback. ``` try: answer = call_local_model(messages, timeout_s=20) except Exception: answer = call_remote_model(messages, timeout_s=30) ``` Definisci chiaramente le regole sulla privacy. Alcuni prompt non dovrebbero mai lasciare la macchina. Per questi, in caso di errore blocca l'operazione. ## Limiti e compromessi Lemonade offre il massimo del suo potenziale sui sistemi AMD compatibili con lo stack di runtime appropriato. Questo significa anche che gli aspetti operativi comprendono le capacità dell'hardware, lo stato dei driver, il supporto dei formati dei modelli e la maturità del backend dell'acceleratore. I principali compromessi: - Portabilità: l'accelerazione orientata ad AMD è preziosa, ma i parchi macchine eterogenei potrebbero richiedere più backend. - Disponibilità dei modelli: non tutti i modelli aperti saranno distribuiti in un pacchetto o ottimizzati per ogni percorso di esecuzione. - Vincoli delle NPU: le NPU sono eccellenti per un'inferenza efficiente, ma non tutte le architetture dei modelli o le lunghezze del contesto sono adatte. - Osservabilità: i server locali hanno bisogno di log e metriche proprio come i servizi cloud. - Concorrenza: il portatile di uno sviluppatore non è un cluster di inferenza multi-tenant. Il modo più onesto di vederla è questo: Lemonade non offre capacità per magia. È un livello migliore per servire modelli in locale su hardware client dalle risorse finite. Il vantaggio prestazionale deriva dall'uso del modello giusto, della quantizzazione giusta, dell'acceleratore giusto e di un'API server che tiene questi dettagli fuori dalla tua applicazione. ## Indicazioni pratiche - Usa Lemonade quando vuoi un server LLM locale accelerato da AMD invece di integrare l'inferenza direttamente nella tua app. - Considera GPU, NPU e CPU come destinazioni di esecuzione diverse, con profili differenti di latenza, consumo energetico e compatibilità con i modelli. - Preferisci modelli quantizzati più piccoli che garantiscono una latenza affidabile nelle interazioni rispetto a modelli più grandi che rientrano a malapena nelle risorse disponibili. - Verifica l'accelerazione tramite i log; un server «funzionante» potrebbe comunque essere in esecuzione sulla CPU. - Trasmetti le risposte in streaming, misura il tempo al primo token ed esegui test sotto carico termico prolungato. - Gestisci l'instradamento, il fallback, la riduzione dei prompt e la politica sulla privacy nel gateway della tua applicazione. - Fissa le versioni dei modelli e mantieni piccoli set di valutazione della latenza e della qualità prima di rilasciare funzionalità di AI locale. [Inferenza](/it/blog/tag/inference/)[Open source](/it/blog/tag/open-source/) A [AI Prime Tech](https://aiprimetech.io/it/) AI Prime Tech pubblica questo blog. Gli articoli sono redatti con l'assistenza dell'AI; verifica nella documentazione ufficiale i dettagli specifici della versione, come gli ID dei modelli, i prezzi e i limiti, prima di farvi affidamento. Ottieni accesso all'API Claude a un costo inferiore Un'unica chiave API per Claude Opus 5.5, Sonnet 5, Haiku 4.5 e Fable 5.1, oltre a GPT-6 modelli. Pagamento a consumo, senza abbonamento. [Ottieni la tua chiave API →](/register) AI Prime Tech è un gateway API indipendente di terze parti. Claude™ e Anthropic® sono marchi di Anthropic, PBC. Non si intende suggerire alcuna affiliazione o approvazione.