PennyLane: perché è il framework giusto per il Quantum Machine Learning

Il problema che PennyLane risolve

Prima di PennyLane, costruire un pipeline di Quantum Machine Learning richiedeva di gestire due mondi separati: il codice quantistico (Qiskit, Cirq) e il framework ML classico (PyTorch, TensorFlow). Il punto di giunzione, come calcolare i gradienti del circuito quantistico in modo compatibile con l’ottimizzatore classico, era un problema di ingegneria non banale, spesso risolto con soluzioni ad hoc.

PennyLane è stato progettato per eliminare questa separazione. La sua idea fondamentale è trattare un circuito quantistico esattamente come un layer di una rete neurale: una funzione differenziabile con input, parametri e output, inseribile in qualsiasi computation graph.

L'architettura di PennyLane

Device-agnostic: PennyLane separa la definizione del circuito dall’hardware su cui gira. Lo stesso codice può essere eseguito su `default.qubit` (simulatore CPU), `lightning.gpu` (simulatore NVIDIA CUDA), `qiskit.ibmq` (IBM Quantum), `braket.aws` (Amazon Braket) o qualsiasi altro backend supportato. Questo è fondamentale per il workflow simulatore → hardware che ho descritto nell’articolo precedente.

QNode: è l’unità computazionale di base. Un QNode trasforma una funzione Python che definisce un circuito quantistico in un oggetto callable e differenziabile.

Differenziazione automatica: PennyLane supporta tre modalità di differenziazione:
– `parameter-shift`: esatta, funziona sull’hardware reale, richiede 2 esecuzioni per parametro
– `backprop`: basata su autodiff classico, solo su simulatori statevector, molto più veloce
– `adjoint`: il metodo più efficiente per simulatori CPU/GPU, non disponibile su hardware

La scelta del metodo dipende dal backend e dal trade-off tra velocità e accuratezza.

Integrazione nativa con ML frameworks:

Con PyTorch
Con JAX

Questo significa che un circuito PennyLane può essere usato come layer in un modello PyTorch ibrido, con forward e backward pass gestiti in modo trasparente.

Il pipeline pratico: dalla prototipazione all'esecuzione

Fase 1 — Sviluppo su simulatore statevector

Si parte sempre su `default.qubit` di PennyLane (o equivalente). L’obiettivo è validare la logica del circuito: l’encoding dei dati, la struttura variazionale, la funzione di costo. In questa fase si usano pochi qubit e si verifica che l’ottimizzatore converga.

Fase 2 — Simulatore con noise model

Prima di passare all’hardware, si introduce un modello di rumore realistico. PennyLane permette di usare noise model calibrati sui processori IBM reali tramite integrazione con Qiskit.

Questo step rivela spesso problemi che il simulatore ideale nascondeva: circuiti troppo profondi, parametri ottimizzati per condizioni irrealistiche, encoding incompatibili con l’hardware.

Fase 3 — Transpilazione e ottimizzazione del circuito

Prima di inviare il circuito a un QPU reale, il compilatore lo “transpila”: traduce le porte native del circuito nelle porte fisicamente implementabili dal processore target, e ottimizza il routing dei SWAP. È possibile controllare il livello di ottimizzazione (0–3 in Qiskit). Un circuito ben transpilato può ridurre significativamente il gate count.

Fase 4 — Esecuzione su IBM Quantum

PennyLane supporta l’esecuzione diretta su IBM Quantum tramite il plugin `pennylane-qiskit`. Con un account IBM Quantum (gratuito per ricerca, a pagamento per accesso premium), è possibile inviare job a processori come IBM Eagle, Heron o Falcon.

I job vengono accodati e i risultati restituiti con i conteggi delle misurazioni. Su circuiti variazionali, il loop di ottimizzazione classico interagisce iterativamente con il QPU , ogni step dell’ottimizzatore richiede una o più esecuzioni del circuito.

I template: il livello alto dell'astrazione

PennyLane offre una libreria di templates – layer quantistici riutilizzabili con strutture variazionali collaudate:

`qml.StronglyEntanglingLayers(weights, wires)`: il template più usato per QNN generiche. Alterna rotazioni SU(2) locali ed entanglement CNOT con una struttura che garantisce espressività (alta capacità di approssimare funzioni arbitrarie sul manifold quantistico).

`qml.BasicEntanglerLayers(weights, wires)`: versione semplificata, con solo RX e CNOT. Più leggera, utile su hardware con risorse limitate.

`qml.QAOAEmbedding(features, weights, wires)`: template specifico per QAOA, che combina encoding e ottimizzazione in un’unica struttura.

`qml.AngleEmbedding(features, wires)` e `qml.AmplitudeEmbedding(features, wires, normalize=True)`: i due principali metodi per caricare dati classici in un circuito quantistico. AngleEmbedding usa rotazioni (richiede N qubit per N feature), AmplitudeEmbedding comprime 2^N valori in N qubit sfruttando la sovrapposizione.

PennyLane vs Qiskit: quando scegliere cosa

Non è una competizione. Sono strumenti progettati con obiettivi parzialmente diversi.

Scegli PennyLane quando: costruisci algoritmi variazionali (VQE, QAOA, QNN), vuoi integrazione nativa con PyTorch/JAX, hai bisogno di gradients differenziabili, lavori su Quantum ML.

Scegli Qiskit quando: vuoi massimo controllo su transpilazione e ottimizzazione del circuito per IBM hardware, lavori su algoritmi non variazionali (Shor, Grover), hai bisogno di primitive avanzate di IBM Quantum Runtime (Sampler, Estimator).

Usali insieme quando: sviluppi con PennyLane ma accedi a IBM Quantum tramite il plugin `pennylane-qiskit`, che permette di sfruttare i transpiler di Qiskit per ottimizzare il circuito prima dell’esecuzione sull’hardware IBM. Questo è esattamente il setup che uso nel mio Quantum Labs.

Il catalogo degli algoritmi: una mappa

PennyLane organizza gli algoritmi in moduli specifici: `qml.qchem` per la chimica quantistica e VQE, `qml.qaoa` per QAOA e problemi combinatori, `qml.qnn` per l’integrazione con Keras e PyTorch. Nei prossimi articoli esplorerò ciascuno di questi in dettaglio, con casi d’uso enterprise e implementazioni concrete.