Corso
In questo tutorial ti spiegherò passo dopo passo come eseguire DeepSeek-R1 in locale e come configurarlo con Ollama. Vedremo anche come creare una semplice applicazione RAG che gira sul tuo laptop usando il modello R1, LangChain e Gradio.
Se ti serve solo una panoramica del modello R1, ti consiglio questo articolo su DeepSeek-R1. Per imparare a fare il fine-tuning di R1, ti consiglio questo tutorial sul fine-tuning di DeepSeek-R1. E se preferisci imparare con i video, guarda questo:
Perché eseguire DeepSeek-R1 in locale?
Eseguire DeepSeek-R1 in locale ti dà il pieno controllo sull'esecuzione del modello senza dipendere da server esterni. Ecco alcuni vantaggi dell'eseguire DeepSeek-R1 in locale:
- Privacy e sicurezza: nessun dato lascia il tuo sistema.
- Accesso ininterrotto: evita rate limit, downtime o interruzioni di servizio.
- Prestazioni: ottieni risposte più rapide con inferenza locale, evitando la latenza delle API.
- Personalizzazione: modifica i parametri, affina i prompt e integra il modello nelle applicazioni locali.
- Convenienza economica: elimina i costi delle API eseguendo il modello in locale.
- Disponibilità offline: lavora senza connessione internet una volta scaricato il modello.
Configurare DeepSeek-R1 in locale con Ollama
Ollama semplifica l'esecuzione locale degli LLM gestendo in modo trasparente download, quantizzazione ed esecuzione dei modelli.
Passo 1: Installa Ollama
Per prima cosa, scarica e installa Ollama dal sito ufficiale.

Una volta completato il download, installa l'applicazione Ollama come faresti con qualsiasi altra applicazione.
Passo 2: Scarica ed esegui DeepSeek-R1
Testiamo la configurazione e scarichiamo il modello. Avvia il terminale e digita il seguente comando.
ollama run deepseek-r1
Ollama offre una gamma di modelli DeepSeek R1, da 1.5B di parametri fino al modello completo da 671B. Il modello da 671B è l'originale DeepSeek-R1, mentre i modelli più piccoli sono versioni distillate basate sulle architetture Qwen e Llama. Se il tuo hardware non supporta il modello da 671B, puoi eseguire facilmente una versione più piccola usando il seguente comando e sostituendo la X qui sotto con la dimensione di parametro desiderata (1.5b, 7b, 8b, 14b, 32b, 70b, 671b):
ollama run deepseek-r1:Xb
Con questa flessibilità, puoi sfruttare le capacità di DeepSeek-R1 anche senza avere un supercomputer.
Passo 3: Eseguire DeepSeek-R1 in background
Per eseguire DeepSeek-R1 in modo continuativo ed esporlo tramite un'API, avvia il server Ollama:
ollama serve
In questo modo il modello sarà disponibile per l'integrazione con altre applicazioni.
Usare DeepSeek-R1 in locale
Passo 1: Eseguire l'inferenza via CLI
Una volta scaricato il modello, puoi interagire con DeepSeek-R1 direttamente dal terminale.

Passo 2: Accedere a DeepSeek-R1 tramite API
Per integrare DeepSeek-R1 nelle applicazioni, usa l'API di Ollama con curl:
curl http://localhost:11434/api/chat -d '{
"model": "deepseek-r1",
"messages": [{ "role": "user", "content": "Solve: 25 * 25" }],
"stream": false
}'
curl è uno strumento da riga di comando nativo di Linux ma funziona anche su macOS. Consente di effettuare richieste HTTP direttamente dal terminale, risultando ottimo per interagire con le API.

Passo 3: Accedere a DeepSeek-R1 tramite Python
Possiamo usare Ollama in qualsiasi IDE preferito. Puoi installare il pacchetto Python di Ollama con il seguente comando:
!pip install ollama
Una volta installato Ollama, usa il seguente script per interagire con il modello:
import ollama
response = ollama.chat(
model="deepseek-r1",
messages=[
{"role": "user", "content": "Explain Newton's second law of motion"},
],
)
print(response["message"]["content"])
La funzione ollama.chat() accetta il nome del modello e un prompt dell'utente, gestendolo come uno scambio conversazionale. Lo script poi estrae e stampa la risposta del modello.

Eseguire un'app Gradio locale per RAG con DeepSeek-R1
Costruiamo una semplice app demo con Gradio per interrogare e analizzare documenti con DeepSeek-R1.
Passo 1: Prerequisiti
Prima di passare all'implementazione, assicuriamoci di avere installati i seguenti strumenti e librerie:
- Python 3.8+
- Langchain: framework per creare applicazioni basate su large language model (LLM), che semplifica retrieval, ragionamento e integrazione di strumenti.
- Chromadb: un database vettoriale ad alte prestazioni pensato per ricerche di similarità efficienti e archiviazione di embedding.
- Gradio: per creare un'interfaccia web facile da usare.
Esegui i seguenti comandi per installare le dipendenze necessarie:
!pip install langchain chromadb gradio
!pip install -U langchain-community
Una volta installate le dipendenze, esegui i seguenti import:
import gradio as gr
from langchain_community.document_loaders import PyMuPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain_community.embeddings import OllamaEmbeddings
import ollama
Passo 2: Elaborare il PDF caricato
Una volta importate le librerie, elaboreremo il PDF caricato.
def process_pdf(pdf_bytes):
if pdf_bytes is None:
return None, None, None
loader = PyMuPDFLoader(pdf_bytes)
data = loader.load()
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, chunk_overlap=100
)
chunks = text_splitter.split_documents(data)
embeddings = OllamaEmbeddings(model="deepseek-r1")
vectorstore = Chroma.from_documents(
documents=chunks, embedding=embeddings, persist_directory="./chroma_db"
)
retriever = vectorstore.as_retriever()
return text_splitter, vectorstore, retriever
La funzione process_pdf:
- Carica e prepara il contenuto del PDF per risposte basate su retrieval.
- Controlla se è stato caricato un PDF.
- Estrae il testo usando
PyMuPDFLoader. - Divide il testo in chunk con
RecursiveCharacterTextSplitter. - Genera embedding vettoriali con
OllamaEmbeddings. - Archivia gli embedding in un vector store Chroma per un retrieval efficiente.
Passo 3: Combinare i chunk di documento recuperati
Una volta recuperati gli embedding, dobbiamo unirli. La funzione combine_docs() unisce più chunk di documento recuperati in una singola stringa.
def combine_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
Poiché i modelli basati su retrieval estraggono passaggi pertinenti e non interi documenti, questa funzione assicura che il contenuto estratto resti leggibile e correttamente formattato prima di essere passato a DeepSeek-R1.
Passo 4: Interrogare DeepSeek-R1 usando Ollama
Ora il nostro input per il modello è pronto. Configuriamo DeepSeek R1 con Ollama.
import re
def ollama_llm(question, context):
formatted_prompt = f"Question: {question}\n\nContext: {context}"
response = ollama.chat(
model="deepseek-r1",
messages=[{"role": "user", "content": formatted_prompt}],
)
response_content = response["message"]["content"]
# Remove content between <think> and </think> tags to remove thinking output
final_answer = re.sub(r"<think>.*?</think>", "", response_content, flags=re.DOTALL).strip()
return final_answer
La funzione ollama_llm() formatta la domanda dell'utente e il contesto recuperato in un prompt strutturato. Questo input formattato viene poi inviato a DeepSeek-R1 tramite ollama.chat(), che elabora la domanda nel contesto fornito e restituisce una risposta pertinente. Se ti serve la risposta senza lo script di ragionamento del modello, usa la funzione strip() per ottenere la risposta finale.
Passo 5: La pipeline RAG
Ora che abbiamo tutti i componenti necessari, costruiamo la pipeline RAG per la nostra demo.
def rag_chain(question, text_splitter, vectorstore, retriever):
retrieved_docs = retriever.invoke(question)
formatted_content = combine_docs(retrieved_docs)
return ollama_llm(question, formatted_content)
La funzione qui sopra cerca prima nel vector store usando retriever.invoke(question), restituendo i passaggi più pertinenti. Questi estratti vengono formattati in un input strutturato con la funzione combine_docs e inviati a ollama_llm, garantendo che DeepSeek-R1 generi risposte ben informate basate sul contenuto recuperato.
Passo 6: Creare l'interfaccia Gradio
La pipeline RAG è pronta. Ora possiamo creare in locale l'interfaccia Gradio insieme al modello DeepSeek-R1 per elaborare un PDF e porre domande sul suo contenuto.
def ask_question(pdf_bytes, question):
text_splitter, vectorstore, retriever = process_pdf(pdf_bytes)
if text_splitter is None:
return None # No PDF uploaded
result = rag_chain(question, text_splitter, vectorstore, retriever)
return {result}
interface = gr.Interface(
fn=ask_question,
inputs=[
gr.File(label="Upload PDF (optional)"),
gr.Textbox(label="Ask a question"),
],
outputs="text",
title="Ask questions about your PDF",
description="Use DeepSeek-R1 to answer your questions about the uploaded PDF document.",
)
interface.launch()
Eseguiamo i seguenti passaggi:
- Verificare se è stato caricato un PDF.
- Elaborare il PDF con la funzione
process_pdfper estrarre il testo e generare gli embedding dei documenti. - Passare la domanda dell'utente e gli embedding dei documenti alla funzione
rag_chain()per recuperare le informazioni pertinenti e generare una risposta contestuale accurata. - Configurare un'interfaccia web basata su Gradio per consentire agli utenti di caricare un PDF e porre domande sul suo contenuto.
- Definire il layout usando la funzione
gr.Interface(), accettando un file PDF e una query testuale come input. - Avviare l'applicazione con
interface.launch()per abilitare una Q&A interattiva basata su documenti tramite browser.

Conclusione
Eseguire DeepSeek-R1 in locale con Ollama consente un'inferenza più veloce, privata ed economica. Con un processo di installazione semplice, interazione da CLI, supporto API e integrazione Python, puoi usare DeepSeek-R1 per molte applicazioni di AI, da domande generiche a task complessi basati su retrieval.
Per restare aggiornato sugli ultimi sviluppi dell'AI, ti consiglio questi blog:
Sono una Google Developers Expert in ML (Gen AI), una Kaggle 3x Expert e una Women Techmakers Ambassador con oltre 3 anni di esperienza nel tech. Ho co-fondato una startup health-tech nel 2020 e sto conseguendo un master in informatica al Georgia Tech, con specializzazione in machine learning.


