Cos'è PyTorch (2026)? Guida completa e Tutorial da Zero
Pytorch 101

Pytorch è un framework di deep learning open source per creare reti neurali con la massima flessibilità.
Seppur sia molto popolare nel mondo Python, pytorch è un wrapper sull'implementazione altamente performante scritta in C++ con supporto ottimizzato a svariati acceleratori hardware come le GPU. Questo design ibrido permette agli sviluppatori di godere della sintassi pulita e flessibile di Python, senza sacrificare la velocità di calcolo necessaria per addestrare modelli complessi su dataset enormi.
Sviluppato originariamente dal team FAIR (Facebook AI Research) di Meta e ora gestito dalla PyTorch Foundation sotto la Linux Foundation, questo framework ha guadagnato terreno diventando lo standard de facto per la ricerca accademica e per la produzione industriale.
Tensori
Al centro di ogni operazione in PyTorch risiede il Tensore. Concettualmente simile agli array di NumPy, il tensore è una struttura dati multidimensionale che funge da blocco costitutivo per i dati di input, output e per i parametri della rete neurale.
Tuttavia, i tensori di PyTorch offrono due vantaggi cruciali rispetto ai classici array:
- Accelerazione Hardware: A differenza degli array NumPy che risiedono sulla CPU, i tensori possono essere spostati ed elaborati sulla GPU (Graphics Processing Unit) o altri acceleratori hardware supportati.
- Integrazione con il Grafo Computazionale: I tensori tengono traccia delle operazioni matematiche eseguite su di essi, una caratteristica fondamentale per il calcolo automatico dei gradienti (come vedremo nella sezione AutoGrad).
Per sfruttare al massimo il parallelismo dell'hardware, i dati vengono caricati in batch, dove un batch non è altro che una lista di sequenze N-dimensionali. Ad esempio, un batch B di L token testuali, diventa un tensore di shape , processato successivamente come se fosse un atomo dalla GPU.
Se state lavorando con immagini, testo o audio, il primo passo in PyTorch è sempre la conversione dei dati in tensori:
- In NLP le parole vengono convertite in "token", sequenze 1D di numeri che possono essere caricati in un LongTensor
- In Computer Vision le immagini, seppur nativamente matrici numeriche vengono convertite in formato , normalizzate e caricate in un FloatTensor
E così via per tutti gli altri formati di input!
AutoGrad
Una delle caratteristiche fondamentali di PyTorch è AutoGrad, il suo motore di differenziazione automatica. Nell'addestramento delle reti neurali, l'algoritmo di Backpropagation richiede il calcolo delle derivate (gradienti) dell'errore rispetto a ciascun parametro della rete.
AutoGrad gestisce questo processo automaticamente grazie a un grafo computazionale dinamico (Define-by-Run). Ciò significa che:
- Il grafo viene costruito "al volo" mentre si eseguono le operazioni.
- Non è necessario definire l'intera architettura della rete in anticipo (come avveniva in TensorFlow 1.x).
- È sufficiente invocare il metodo
.backward()sul tensore della funzione di costo (loss) per calcolare i gradienti per tutti i tensori che hanno contribuito a quel risultato.
Questa flessibilità rende PyTorch ideale per il debugging e per la costruzione di architetture complesse che cambiano comportamento durante l'esecuzione (es. language models con input di lunghezza variabile).
Addestrare una rete in PyTorch
L'addestramento di un modello in PyTorch segue un "training loop" standardizzato e trasparente, che offre allo sviluppatore il controllo completo su ogni passaggio. Il processo si articola generalmente in quattro fasi cicliche:
- Forward Pass: I dati di input vengono passati attraverso la rete per ottenere una predizione.
- Calcolo della Loss: Si confronta la predizione con l'etichetta reale (ground truth) utilizzando una funzione di costo (es. CrossEntropyLoss o MSELoss, ecc).
- Backward Pass: Attraverso
loss.backward(), AutoGrad calcola i gradienti, determinando la direzione in cui aggiornare i pesi per ridurre l'errore. - Ottimizzazione: L'ottimizzatore (es. SGD, Adam, ecc) aggiorna i parametri del modello basandosi sui gradienti calcolati.
È fondamentale ricordare di azzerare i gradienti all'inizio di ogni iterazione (optimizer.zero_grad()), altrimenti PyTorch li accumulerebbe, portando a risultati errati.
Ecco un esempio self-contained di training loop che puoi copiare e incollare nel tuo notebook:
import torch
import torch.nn as nn
import torch.optim as optim
# 1. PREPARAZIONE DEI DATI (TENSORI)
# Input (X) e Output atteso (y).
# La relazione che la rete deve imparare è y = 2x
X = torch.tensor([[1.0], [2.0], [3.0], [4.0]])
y = torch.tensor([[2.0], [4.0], [6.0], [8.0]])
# 2. DEFINIZIONE DEL MODELLO
# Usiamo un semplice layer lineare: y = wx + b
# La rete inizierà con pesi (w) e bias (b) casuali.
model = nn.Linear(in_features=1, out_features=1)
# 3. LOSS FUNCTION E OTTIMIZZATORE
# MSELoss calcola l'errore quadratico medio (quanto siamo lontani dal vero valore?)
criterion = nn.MSELoss()
# SGD (Stochastic Gradient Descent) aggiornerà i pesi.
# lr (learning rate) determina quanto velocemente la rete apprende.
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 4. TRAINING LOOP
epochs = 100 # Numero di volte che la rete vede tutti i dati
print(f"Loss iniziale: {criterion(model(X), y).item():.4f}") # Errore prima dell'addestramento
for epoch in range(epochs):
# A. Azzeramento dei gradienti
# Fondamentale: PyTorch accumula i gradienti per default,
# quindi dobbiamo resettarli a ogni iterazione.
optimizer.zero_grad()
# B. Forward Pass (Predizione)
outputs = model(X)
# C. Calcolo della Loss (Errore)
loss = criterion(outputs, y)
# D. Backward Pass (Calcolo dei gradienti)
loss.backward()
# E. Ottimizzazione (Aggiornamento dei pesi)
optimizer.step()
if (epoch+1) % 20 == 0:
print(f'Epoca [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')
# TEST FINALE
new_val = torch.tensor([[5.0]])
prediction = model(new_val)
print(f"\nDopo l'addestramento, se x=5, la rete predice y={prediction.item():.2f} (Atteso: 10.0)")
Ecosistema PyTorch
La forza di PyTorch non risiede solo nel core framework, ma in un ecosistema modulare che estende le sue capacità e ottimizzazioni a domini specifici:
- TorchVision: La libreria di riferimento per la Computer Vision. Offre dataset standard, trasformazioni per l'image augmentation e architetture pre-addestrate (come ResNet o ViT).
- TorchAudio: Specializzata nell'elaborazione del segnale audio, fornisce strumenti per il caricamento di file audio e la trasformazione in spettrogrammi.
- TorchText: Fornisce primitive per l'elaborazione del linguaggio naturale (NLP), sebbene l'industria stia gradualmente migrando verso soluzioni più integrate come quelle di HuggingFace.
- TorchRL: Una libreria dedicata all'apprendimento per rinforzo (Reinforcement Learning), offrendo primitive modulari per costruire agenti.
- TorchTitan: Una recente aggiunta all'ecosistema, progettata specificamente per il training distribuito su larga scala di LLM (Large Language Models), ottimizzando l'uso di cluster di GPU.
HuggingFace Transformers
Impossibile parlare di PyTorch oggi senza citare HuggingFace. La libreria transformers è costruita principalmente su PyTorch e ha democratizzato l'accesso allo stato dell'arte del Deep Learning (come BERT, GPT, Llama). Grazie alla perfetta interoperabilità, è possibile scaricare un modello con due righe di codice e integrarlo immediatamente in un training loop nativo di PyTorch.
PyTorch 2.0 e la rivoluzione di torch.compile
Se fino a qualche anno fa il dilemma era scegliere tra la flessibilità di PyTorch (Eager Mode) e le prestazioni in prod (Graph Mode), con l'avvento di PyTorch 2.0 questo divario è stato colmato. La vera svolta per chi sviluppa oggi nel 2026 si chiama torch.compile.
Fino alla versione 1.x, PyTorch eseguiva le operazioni Python riga per riga. Questo è ottimo per il debugging, ma inefficiente per l'hardware, poiché la CPU deve continuamente "inviare" piccoli pacchetti di lavoro alla GPU.
torch.compile risolve questo problema introducendo un compilatore JIT (Just-In-Time) opzionale ma potentissimo. Il funzionamento si basa su due tecnologie chiave:
- TorchDynamo: Cattura il grafo computazionale dal tuo codice Python in modo sicuro (se non capisce qualcosa, torna alla modalità classica senza rompersi).
- TorchInductor: Compila questo grafo in codice macchina altamente ottimizzato (usando Triton per le GPU o C++ per le CPU).
Il risultato? Un aumento delle prestazioni che spesso varia dal 30% al 200%, semplicemente aggiungendo una riga di codice.
Come si usa (La "One-Line Experience")
Non serve riscrivere il modello o cambiare il training loop:
import torch
# ... definizione standard del modello ...
model = MyNeuralNetwork()
# OTTIMIZZAZIONE
# Questa singola riga compila il modello per la massima efficienza.
# 'mode' può essere impostato su 'default', 'reduce-overhead' o 'max-autotune'
# a seconda di quanta memoria/tempo di compilazione vuoi sacrificare.
optimized_model = torch.compile(model, mode="default")
# Da qui in poi, usa optimized_model esattamente come usavi model
optimizer = torch.optim.Adam(optimized_model.parameters())
output = optimized_model(input_data)
Nota bene: La prima volta che eseguite un forward pass con il modello compilato, noterete un ritardo. È il momento in cui PyTorch sta analizzando il codice e generando i kernel ottimizzati (fase di warm-up). Le esecuzioni successive saranno drasticamente più veloci perché il modello eseguirà direttamente il codice compilato, saltando l'overhead di Python.
L'uso di torch.compile è diventato lo standard de facto per l'addestramento di LLM e modelli di Visione, rendendo PyTorch non solo il framework più semplice, ma spesso anche il più veloce.
Come installare pytorch
Ad oggi nel 2026 consiglio di impostare un virtual environment python tramite uv.
Basta installarlo seguendo questa semplice guida ufficiale e lanciare uv add torch==2.9.0 (o la versione che preferisci).
Ad esempio, se dovessi installare uv sul mio mac per la prima volta e creare un nuovo venv python 3.12, questi sono gli step che seguirei:
curl -LsSf https://astral.sh/uv/install.sh | sh # installa uv, solo la prima volta in assoluto!
cd
uv init --python=3.12 --lib esercizi_pytorch # crea nuovo venv 3.12 in una sottocartella chiamata "esercizi_pytorch"
cd esercizi_pytorch/
code . # apri vscode o editor preferito!