Skip to navigationSkip to main contentSkip to footerScaleway DocsAsk our AI
Ask our AI

Run Quantum Machine Learning using Pennylane

Pennylane is an open-source framework for quantum machine learning (QML), automatic differentiation, and optimization of hybrid quantum-classical computations that allows you to write quantum programs in a high-level way, abstracting away the low-level details of the hardware.

It is among the most popular frameworks for quantum machine learning. It offers a high-level interface for building and training quantum circuits in a hardware-agnostic fashion, using Python.

Scaleway offers access to the pennylane-scaleway plugin, which enables you to run your already written Pennylane's circuits on Scaleway's QaaS infrastructure simply by changing its name.

How to use Pennylane with Scaleway

Before you start

To complete the actions presented below, you must have:

  • A Scaleway account with a valid Project ID
  • A Scaleway API Key (Secret Key)
  • Python and pennylane installed on your local machine
  1. Select one of the following devices to use as a Pennylane device:

    • scaleway.aer
    • scaleway.aqt
    • scaleway.iqm (Available soon)
  2. Select which backend to use within the chose device. This will determine the performance of your device. Refer to the detailed list of Scaleweay Quantum Computing offers on the Scaleway Website to find a complete list of the available backend platforms.

  3. Install the pennylane-scaleway provider. Refer to the pennylane-scaleway plugin repository for more information.

    pip install pennylane-scaleway
  4. Create a file with the following computation script. Replace $SCW_PROJECT_ID and $SCW_SECRET_KEY with your Scaleway Project ID and secret key. Also replace the device definition, with the device-backend pair of your choice.

    import pennylane as qml # You are not dreaming, no need to import pennylane-scaleway as long as it is installed in your current environment.
    
    device = qml.device("scaleway.aer",
            wires=2,
            project_id="$SCW_PROJECT_ID",   # Or set SCW_PROJECT_ID environment variable.
            secret_key="$SCW_SECRET_KEY",   # Or set SCW_SECRET_KEY environment variable.
            backend="EMU-AER-16C-128M"
        )
    
    @qml.set_shots(512) # Decorating the circuit with set_shots() is the preferred way of specifying shots.
    @qml.qnode(device)  # The pennylane circuit and its device are defined by the qnode() decorator.
    def my_circuit():   # Define a simple Bell state circuit.
        qml.Hadamard(wires=0)
        qml.CNOT(wires=[0, 1])
        return qml.counts()
    
    result = my_circuit()   # Execute the circuit.
    print(result)
    
    device.stop() # Do not forget to close the session when you are done.

    You can also use the device as a context manager so your session is automatically closed when exiting the context:

    import pennylane as qml
    
    with qml.device("scaleway.aqt",
        project_id="$SCW_PROJECT_ID",
        secret_key="$SCW_SECRET_KEY">,
        backend="EMU-IBEX-12PQ-L4",
    ) as dev:
    
        @qml.set_shots(512)
        @qml.qnode(dev)
        def circuit():
            qml.Hadamard(wires=0)
            qml.CNOT(wires=[0, 1])
            return qml.counts()
    
        result = circuit()
    
    print(result)
  5. Save the script. In this example we save it as pennylane.py.

  6. Run the script.

    python ~/pennylane.py

How to manage a session

A session is automatically created when you instantiate a device. You can manage it manually by calling device.start() and device.stop(), but it is recommended to use the context manager approach instead.

You may also attach to an existing session, handle maximum session duration and idle duration by setting these as keyword arguments when instantiating the device.

For example:

import pennylane as qml

with qml.device("scaleway.aer",
    wires=2,
    project_id="$SCW_PROJECT_ID>",
    secret_key="$SCW_SECRET_KEY>",
    backend="EMU-AER-16C-128M",
    max_duration="1h",
    max_idle_duration="5m"
) as dev:
    ...

Examples

Below is a toy example of a variational quantum circuit, where we find the optimal value of a parameterized rotation on a single qubit to match invert its state (Z-basis).

import pennylane as qml
from pennylane import numpy as np

MAX_ITER = 100
EPSILON = 1e-9

with qml.device("scaleway.aer", wires=1, backend="EMU-AER-16C-128M") as dev:

    # Circuit definition, with a parameterized rotation
    @qml.set_shots(100)
    @qml.qnode(dev)
    def circuit(params):
        qml.RX(params, wires=0)

        # Output is 1 for state |0> and -1 for state |1>
        return qml.expval(qml.PauliZ(0))

    #Loss function
    def cost(params):
        prediction = circuit(params)
        target = -1.0  # TARGET -> We want the qubit to output -1 (the |1> state)
        return np.abs(prediction - target)

    opt = qml.GradientDescentOptimizer(stepsize=0.5)
    params = np.array(0.0, requires_grad=True)

    print(f"Initial rotation: {params:.4f} rad")

    for i in range(MAX_ITER):

        old_params = params.copy()
        params = opt.step(cost, params)
        delta_params = np.abs(params - old_params)

        cost_t = cost(params)

        print(f"Step {i}: Delta params = {delta_params:.4f} rad, Cost = {cost_t:.6f}")

        if cost_t < EPSILON and delta_params < EPSILON:
            print("Converged!")
            break

print(f"\nFinal rotation: {params % (2*np.pi):.4f} rad (Target: Pi approx 3.14)")

Gradient descent is handled by PennyLane, even on real hardware, by using tricks such as parameter-shifting.

With a bit of luck you should get a result close to pi radians. The difference is due to a plateau near the optimal solution:

Initial rotation: 0.0000 rad
Step 0: Delta params = 0.0150 rad, Cost = 2.000000
Step 1: Delta params = 0.0300 rad, Cost = 2.000000
Step 2: Delta params = 0.0450 rad, Cost = 2.000000
Step 3: Delta params = 0.0200 rad, Cost = 2.000000
Step 4: Delta params = 0.0450 rad, Cost = 1.980000
Step 5: Delta params = 0.1450 rad, Cost = 1.940000
Step 6: Delta params = 0.0900 rad, Cost = 1.920000
Step 7: Delta params = 0.1750 rad, Cost = 1.920000
Step 8: Delta params = 0.2400 rad, Cost = 1.800000
Step 9: Delta params = 0.3550 rad, Cost = 1.360000
Step 10: Delta params = 0.4550 rad, Cost = 1.060000
Step 11: Delta params = 0.5000 rad, Cost = 0.540000
Step 12: Delta params = 0.4350 rad, Cost = 0.140000
Step 13: Delta params = 0.2950 rad, Cost = 0.080000
Step 14: Delta params = 0.1250 rad, Cost = 0.000000
Step 15: Delta params = 0.0000 rad, Cost = 0.000000
Converged!

Final rotation: 2.9100 rad (Target: Pi approx 3.14)
Note

Refer to the pennylane-scaleway plugin repository for more examples.

Still need help?

Create a support ticket
No Results