diff --git a/docs/tutorials/index.mdx b/docs/tutorials/index.mdx
index 6c07939ff14..b43bc5297fb 100644
--- a/docs/tutorials/index.mdx
+++ b/docs/tutorials/index.mdx
@@ -49,7 +49,7 @@ These tutorials focus on estimating physically meaningful quantities, such as en
* [Nishimori phase transition](/docs/tutorials/nishimori-phase-transition)
-* [Ground state energy estimation of the Heisenberg chain with VQE](/docs/tutorials/spin-chain-vqe)
+* [Ground-state energy estimation of the Heisenberg chain with VQE](/docs/tutorials/spin-chain-vqe)
* [Quantum kernel training](/docs/tutorials/quantum-kernel-training)
diff --git a/docs/tutorials/spin-chain-vqe.ipynb b/docs/tutorials/spin-chain-vqe.ipynb
index 092b4d6e552..cee53edd4c3 100644
--- a/docs/tutorials/spin-chain-vqe.ipynb
+++ b/docs/tutorials/spin-chain-vqe.ipynb
@@ -8,13 +8,15 @@
},
"source": [
"---\n",
- "title: Ground state energy estimation of the Heisenberg chain with VQE\n",
- "description: Build, deploy, and run a Qiskit pattern for simulating a Heisenberg chain and estimating its ground state energy.\n",
+ "title: Ground-state energy estimation of the Heisenberg chain with VQE\n",
+ "description: Build, deploy, and run a Qiskit pattern for simulating a Heisenberg chain and estimating its ground-state energy.\n",
"---\n",
"\n",
+ "{/* cspell:ignore hyperparameters, forall, nabla, nparams */}\n",
"\n",
"# Ground-state energy estimation of the Heisenberg chain with VQE\n",
- "*Usage estimate: Two minutes on an Eagle r3 processor (NOTE: This is an estimate only. Your runtime might vary.)*"
+ "\n",
+ "*Usage estimate: 37 minutes on a Heron processor (NOTE: This is an estimate only. Your runtime might vary.)*"
]
},
{
@@ -24,7 +26,7 @@
"source": [
"## Background\n",
"\n",
- "This tutorial shows how to build, deploy, and run a `Qiskit pattern` for simulating a Heisenberg chain and estimating its ground state energy. For more information about `Qiskit patterns` and how `Qiskit Serverless` can be used to deploy them to the cloud for managed execution, visit our [docs page on IBM Quantum® Platform](/docs/guides/serverless)."
+ "This tutorial shows how to build, deploy, and run a development workflow called a [Qiskit pattern](/docs/guides/intro-to-patterns) for simulating a Heisenberg chain and estimating its ground-state energy using the SPSA optimizer."
]
},
{
@@ -36,10 +38,8 @@
"\n",
"Before starting this tutorial, ensure that you have the following installed:\n",
"\n",
- "* Qiskit SDK v1.2 or later, with [visualization](/docs/api/qiskit/visualization) support\n",
- "* Qiskit Runtime v0.28 or later (`pip install qiskit-ibm-runtime`)\n",
- "* Qiskit Serverless (pip install qiskit_serverless)\n",
- "* IBM Catalog (pip install qiskit-ibm-catalog)"
+ "* Qiskit SDK v2.0 or later, with [visualization](/docs/api/qiskit/visualization) support\n",
+ "* Qiskit Runtime v0.44 or later (`pip install qiskit-ibm-runtime`)"
]
},
{
@@ -52,21 +52,18 @@
},
{
"cell_type": "code",
- "execution_count": 1,
- "id": "c37bfdb1-bb7c-4177-a3af-37ec32558fd0",
+ "execution_count": 3,
+ "id": "e7754922",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
- "\n",
- "from scipy.optimize import minimize\n",
"from typing import Sequence\n",
"\n",
- "\n",
"from qiskit import QuantumCircuit\n",
"from qiskit.quantum_info import SparsePauliOp\n",
- "from qiskit.primitives.base import BaseEstimatorV2\n",
+ "from qiskit.primitives import BaseEstimatorV2\n",
"from qiskit.circuit.library import XGate\n",
"from qiskit.circuit.library import efficient_su2\n",
"from qiskit.transpiler import PassManager\n",
@@ -75,55 +72,14 @@
" ALAPScheduleAnalysis,\n",
" PadDynamicalDecoupling,\n",
")\n",
+ "from qiskit_ibm_runtime import QiskitRuntimeService, Session, EstimatorV2\n",
"\n",
- "from qiskit_ibm_runtime import QiskitRuntimeService\n",
- "from qiskit_ibm_runtime import Session, Estimator\n",
"\n",
- "from qiskit_ibm_catalog import QiskitServerless, QiskitFunction"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "faef6e0d-f09d-46fb-8b4f-e1b56f7c6b3a",
- "metadata": {},
- "outputs": [],
- "source": [
"def visualize_results(results):\n",
" plt.plot(results[\"cost_history\"], lw=2)\n",
- " plt.xlabel(\"Iteration\")\n",
+ " plt.xlabel(\"Number of function evaluations\")\n",
" plt.ylabel(\"Energy\")\n",
- " plt.show()\n",
- "\n",
- "\n",
- "def build_callback(\n",
- " ansatz: QuantumCircuit,\n",
- " hamiltonian: SparsePauliOp,\n",
- " estimator: BaseEstimatorV2,\n",
- " callback_dict: dict,\n",
- "):\n",
- " def callback(current_vector):\n",
- " # Keep track of the number of iterations\n",
- " callback_dict[\"iters\"] += 1\n",
- " # Set the prev_vector to the latest one\n",
- " callback_dict[\"prev_vector\"] = current_vector\n",
- " # Compute the value of the cost function at the current vector\n",
- " current_cost = (\n",
- " estimator.run([(ansatz, hamiltonian, [current_vector])])\n",
- " .result()[0]\n",
- " .data.evs[0]\n",
- " )\n",
- " callback_dict[\"cost_history\"].append(current_cost)\n",
- " # Print to screen on single line\n",
- " print(\n",
- " \"Iters. done: {} [Current cost: {}]\".format(\n",
- " callback_dict[\"iters\"], current_cost\n",
- " ),\n",
- " end=\"\\r\",\n",
- " flush=True,\n",
- " )\n",
- "\n",
- " return callback"
+ " plt.show()"
]
},
{
@@ -136,12 +92,12 @@
"* Input: Number of spins\n",
"* Output: Ansatz and Hamiltonian modeling the Heisenberg chain\n",
"\n",
- "Construct an ansatz and Hamiltonian which model a 10-spin Heisenberg chain. First, we import some generic packages and create a couple of helper functions."
+ "Construct an ansatz and Hamiltonian that model a 10-spin Heisenberg chain. First, we import some generic packages and create some helper functions."
]
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": null,
"id": "7e8d2f10-f1d6-4ec2-bac9-9db23499c9e1",
"metadata": {},
"outputs": [
@@ -151,17 +107,20 @@
""
]
},
- "execution_count": 3,
+ "execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"num_spins = 10\n",
- "ansatz = efficient_su2(num_qubits=num_spins, reps=3)\n",
+ "ansatz = efficient_su2(num_qubits=num_spins, reps=2)\n",
"\n",
- "# Remember to insert your token in the QiskitRuntimeService constructor\n",
- "service = QiskitRuntimeService()\n",
+ "service = QiskitRuntimeService(\n",
+ " channel=\"ibm_cloud\",\n",
+ " token=\"\", # Replace with your actual API token\n",
+ " instance=\"\", # Replace with your instance name if needed\n",
+ ")\n",
"backend = service.least_busy(\n",
" operational=True, min_num_qubits=num_spins, simulator=False\n",
")\n",
@@ -200,7 +159,7 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 5,
"id": "a0a5f1c8-5c31-4d9f-ae81-37bd67271d44",
"metadata": {},
"outputs": [
@@ -210,14 +169,14 @@
""
]
},
- "execution_count": 4,
+ "execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"target = backend.target\n",
- "pm = generate_preset_pass_manager(optimization_level=3, backend=backend)\n",
+ "pm = generate_preset_pass_manager(optimization_level=3, target=target)\n",
"pm.scheduling = PassManager(\n",
" [\n",
" ALAPScheduleAnalysis(durations=target.durations()),\n",
@@ -228,9 +187,9 @@
" ),\n",
" ]\n",
")\n",
- "ansatz_ibm = pm.run(ansatz)\n",
- "observable_ibm = hamiltonian.apply_layout(ansatz_ibm.layout)\n",
- "ansatz_ibm.draw(\"mpl\", scale=0.6, style=\"iqp\", fold=-1, idle_wires=False)"
+ "isa_ansatz = pm.run(ansatz)\n",
+ "isa_observable = hamiltonian.apply_layout(isa_ansatz.layout)\n",
+ "isa_ansatz.draw(\"mpl\", scale=0.6, style=\"iqp\", fold=-1, idle_wires=False)"
]
},
{
@@ -243,147 +202,232 @@
"* Input: Target circuit and observable\n",
"* Output: Results of optimization\n",
"\n",
- "Minimize the estimated ground state energy of the system by optimizing the circuit parameters. Use the `Estimator` primitive from Qiskit Runtime to evaluate the cost function during optimization.\n",
+ "Minimize the estimated ground-state energy of the system by optimizing the circuit parameters. Use the `Estimator` primitive from Qiskit Runtime to evaluate the cost function during optimization.\n",
+ "\n",
+ "Since we optimized the circuit for the backend in Step 2, we can avoid doing transpilation on the Runtime server by setting `skip_transpilation=True` and passing the optimized circuit. For this demo, we will run on a QPU using `qiskit-ibm-runtime` primitives. To run with `qiskit` statevector-based primitives, replace the block of code using Qiskit Runtime primitives with the commented block.\n",
"\n",
- "For this demo, we will run on a QPU using `qiskit-ibm-runtime` primitives. To run with `qiskit` statevector-based primitives, replace the block of code using Qiskit IBM Runtime primitives with the commented block."
+ "In this tutorial we use Simultaneous Perturbation Stochastic Approximation (SPSA), which is a gradient-based optimizer. Next we give a brief introduction to it, and provide the code to implement SPSA using Qiskit v2.0."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "64f97e6f",
+ "metadata": {},
+ "source": [
+ "### Introducing SPSA\n",
+ "\n",
+ "Simultaneous Perturbation Stochastic Approximation (SPSA) [\\[1\\]](#references) is an optimization algorithm that approximates the entire gradient vector using only two function calls at each iteration. Let $f:\\mathbb{R}^p\\rightarrow \\mathbb{R}$ be the cost function with $p$ parameters to be optimized, and $x_i\\in \\mathbb{R}^p$ be the parameter vector at the $i^{th}$ step of the iteration. To compute the gradient, a random vector $\\Delta_i$ of size $p$ is created, where each element $\\Delta_{ij}$, $\\forall$ $j\\in \\{1,2,...,p\\}$, is uniformly sampled from $\\{-1, 1\\}$. Next, each element of the random vector $\\Delta_i$ is multiplied with a small value $c_i$ to create a random perturbation. The gradient is then estimated as\n",
+ "\n",
+ "$$[\\nabla f(x_i)]_j \\approx \\frac{f(x_i + c_i \\Delta_i) - f(x_i - c_i \\Delta_i)}{2c_i\\Delta_{ij}}.$$\n",
+ "\n",
+ "Intuitively, since a random perturbation is applied during the gradient estimation, it is expected that small deviations in the exact values of $f$ coming from noise can be tolerated and accounted for. In fact, SPSA is particularly known to be robust against noise, and requires only two hardware calls for each iteration. It is, therefore, one of the highly preferred optimizers for implementing variational algorithms.\n",
+ "\n",
+ "In this tutorial, the hyperparameters for the $i^{th}$ iteration, $a_i$ and $c_i$, are computed as $a_i = a/(A + i + 1)^\\alpha$ and $c_i = c / (i+1)^\\gamma$, where the constant values are taken as $A = 30$, $\\alpha = 0.9$, $a = 0.3$, $c = 0.1$, and $\\gamma = 0.4$. These values are selected from [\\[2\\]](#references). Appropriate tuning of hyperparameters is necessary for extracting a good performance out of SPSA."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "73a9352c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def spsa(\n",
+ " fun, x0, args=(), A=30, alpha=0.9, a=0.3, c=0.1, gamma=0.4, maxiter=100\n",
+ "):\n",
+ " nparams = len(x0)\n",
+ " x = np.copy(x0)\n",
+ "\n",
+ " for i in range(maxiter):\n",
+ " a_i = a / (A + i + 1) ** alpha\n",
+ " c_i = c / (i + 1) ** gamma\n",
+ " delta_i = np.random.choice([-1, 1], nparams)\n",
+ "\n",
+ " # two hardware calls\n",
+ " eval_1 = fun(x + c_i * delta_i, *args)\n",
+ " eval_2 = fun(x - c_i * delta_i, *args)\n",
+ "\n",
+ " # compute the gradient and update the parameters\n",
+ " grad = (eval_1 - eval_2) / (2 * c_i) * np.reciprocal(delta_i)\n",
+ " x = x - a_i * grad\n",
+ "\n",
+ " return x"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "4c4b1b0b-5c61-4587-986c-7a9108bc2505",
+ "id": "32ca3b6a",
"metadata": {},
"outputs": [],
"source": [
- "# SciPy minimizer routine\n",
"def cost_func(\n",
" params: Sequence,\n",
" ansatz: QuantumCircuit,\n",
" hamiltonian: SparsePauliOp,\n",
" estimator: BaseEstimatorV2,\n",
+ " cost_history_dict: dict,\n",
") -> float:\n",
" \"\"\"Ground state energy evaluation.\"\"\"\n",
- " return (\n",
- " estimator.run([(ansatz, hamiltonian, [params])])\n",
- " .result()[0]\n",
- " .data.evs[0]\n",
+ " energy = (\n",
+ " estimator.run([(ansatz, hamiltonian, [params])]).result()[0].data.evs\n",
" )\n",
"\n",
+ " cost_history_dict[\"iters\"] += 1\n",
+ " cost_history_dict[\"prev_vector\"] = list(params)\n",
+ " cost_history_dict[\"cost_history\"].append(float(energy[0]))\n",
"\n",
- "num_params = ansatz_ibm.num_parameters\n",
- "params = 2 * np.pi * np.random.random(num_params)\n",
+ " print(\n",
+ " f\"Fx Iters. done: {cost_history_dict['iters']} [Current cost: {round(energy[0], 5)}]\",\n",
+ " end=\"\\r\",\n",
+ " )\n",
"\n",
- "callback_dict = {\n",
- " \"prev_vector\": None,\n",
- " \"iters\": 0,\n",
- " \"cost_history\": [],\n",
- "}\n",
+ " return energy\n",
+ "\n",
+ "\n",
+ "def solve(x0, isa_ansatz, isa_observable, maxiter=150):\n",
+ " cost_history_dict = {\n",
+ " \"prev_vector\": None,\n",
+ " \"iters\": 0,\n",
+ " \"cost_history\": [],\n",
+ " \"y_min\": None,\n",
+ " }\n",
+ "\n",
+ " # Evaluate the problem using a QPU via Qiskit IBM Runtime\n",
+ " with Session(backend=backend) as session:\n",
+ " estimator = EstimatorV2(mode=session)\n",
+ " estimator.skip_transpilation = True\n",
+ " x_opt = spsa(\n",
+ " cost_func,\n",
+ " x0=x0,\n",
+ " args=(isa_ansatz, isa_observable, estimator, cost_history_dict),\n",
+ " maxiter=maxiter,\n",
+ " )\n",
"\n",
- "# Evaluate the problem on a QPU by using Qiskit IBM Runtime\n",
- "with Session(backend=backend) as session:\n",
- " estimator = Estimator()\n",
- " callback = build_callback(\n",
- " ansatz_ibm, observable_ibm, estimator, callback_dict\n",
- " )\n",
- " res = minimize(\n",
- " cost_func,\n",
- " x0=params,\n",
- " args=(ansatz_ibm, observable_ibm, estimator),\n",
- " callback=callback,\n",
- " method=\"cobyla\",\n",
- " options={\"maxiter\": 100},\n",
- " )\n",
+ " y_min = cost_func(\n",
+ " x_opt, isa_ansatz, isa_observable, estimator, cost_history_dict\n",
+ " )\n",
"\n",
- "visualize_results(callback_dict)"
+ " return y_min, cost_history_dict"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "f418b372",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "np.random.seed(42)\n",
+ "num_params = ansatz.num_parameters\n",
+ "params = 2 * np.pi * np.random.random(num_params)"
]
},
{
"cell_type": "markdown",
- "id": "33abbb3f-6245-4610-a05d-e2bc4cc551f0",
+ "id": "3bf42923",
"metadata": {},
"source": [
- "## Step 4: Post-process and return result in desired classical format\n",
- "\n",
- "* Input: Ground state energy estimates during optimization\n",
- "* Output: Estimated ground state energy"
+ "Here we set the `maxiter = 50`. Note that since each iteration requires two calls to the function to compute the gradient, the total number of function calls will be $2 \\times \\text{maxiter}$. The `maxiter` can be increased to any higher value for better energy estimation."
]
},
{
"cell_type": "code",
- "execution_count": null,
- "id": "e5b58771-d543-4e75-9746-fbc7b28e4360",
+ "execution_count": 8,
+ "id": "1732ce37",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Fx Iters. done: 101 [Current cost: -2.19621]\r"
+ ]
+ }
+ ],
"source": [
- "print(f'Estimated ground state energy: {res[\"fun\"]}')"
+ "maxiter = 50\n",
+ "spsa_min, spsa_history = solve(\n",
+ " params, isa_ansatz, isa_observable, maxiter=maxiter\n",
+ ")"
]
},
{
"cell_type": "markdown",
- "id": "4548f97e-352e-4a8e-b2c7-3c85f12099ab",
+ "id": "33abbb3f-6245-4610-a05d-e2bc4cc551f0",
"metadata": {},
"source": [
- "## Deploy the Qiskit pattern to the cloud\n",
- "\n",
- "To do this, move the source code above to a file, `./source/heisenberg.py`, wrap the code in a script which takes inputs and returns the final solution, and finally upload it to a remote cluster using the `QiskitFunction` class from `qiskit-ibm-catalog`. For guidance on specifying external dependencies, passing input arguments, and more, check out the [Qiskit Serverless guides](/docs/guides/serverless).\n",
+ "## Step 4: Post-process and return result in desired classical format\n",
"\n",
- "The input to the Pattern is the number of spins in the chain. The output is an estimation of the ground state energy of the system."
+ "* Input: Ground-state energy estimates during optimization\n",
+ "* Output: Estimated ground-state energy"
]
},
{
"cell_type": "code",
- "execution_count": null,
- "id": "970c51c8-dac5-4b64-9f20-4067666dfddc",
+ "execution_count": 10,
+ "id": "e5b58771-d543-4e75-9746-fbc7b28e4360",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Estimated ground state energy: [-2.19621239]\n"
+ ]
+ }
+ ],
"source": [
- "# Authenticate to the remote cluster and submit the pattern for remote execution\n",
- "serverless = QiskitServerless()\n",
- "heisenberg_function = QiskitFunction(\n",
- " title=\"ibm_heisenberg\",\n",
- " entrypoint=\"heisenberg.py\",\n",
- " working_dir=\"./source/\",\n",
- ")\n",
- "serverless.upload(heisenberg_function)"
+ "print(f\"Estimated ground state energy: {spsa_min}\")"
]
},
{
- "cell_type": "markdown",
- "id": "e1b5c8d0-229a-4a39-8a8a-daf1762fca54",
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "ecd7762a",
"metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
"source": [
- "### Run the Qiskit pattern as a managed service\n",
+ "results = {\n",
+ " \"spsa\": spsa_history,\n",
+ "}\n",
"\n",
- "Once we have uploaded the pattern to the cloud, we can easily run it using the `QiskitServerless` client."
+ "visualize_results(spsa_history)"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "9d9e5218-bdfe-4897-8920-7d0578a32c7f",
+ "cell_type": "markdown",
+ "id": "217a9379",
"metadata": {},
- "outputs": [],
"source": [
- "# Run the pattern on the remote cluster\n",
+ "## References\n",
"\n",
- "ibm_heisenberg = serverless.load(\"ibm_heisenberg\")\n",
- "job = serverless.run(ibm_heisenberg)\n",
- "solution = job.result()\n",
+ "[1] Spall, J. C. (2002). Implementation of the simultaneous perturbation algorithm for stochastic optimization.\n",
+ "IEEE Transactions on Aerospace and Electronic Systems, 34(3), 817-823.\n",
"\n",
- "print(solution)\n",
- "print(job.logs())"
+ "[2] Sahin, M. Emre, et al. (2025). Qiskit Machine Learning: an open-source library for quantum machine learning tasks at scale on quantum hardware and classical simulators. arXiv:2505.17756."
]
},
{
"cell_type": "markdown",
- "id": "c14b0e0a",
+ "id": "8f14492c",
"metadata": {},
"source": [
- "## Tutorial survey\n",
- "\n",
- "Please take this short survey to provide feedback on this tutorial. Your insights will help us improve our content offerings and user experience.\n",
+ "## Next steps\n",
"\n",
- "[Link to survey](https://your.feedback.ibm.com/jfe/form/SV_bfuBwfNeeFBxnim)"
+ "\n",
+ "If you found this work interesting, you might be interested in the following material:\n",
+ ""
]
}
],
diff --git a/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/7e8d2f10-f1d6-4ec2-bac9-9db23499c9e1-0.avif b/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/7e8d2f10-f1d6-4ec2-bac9-9db23499c9e1-0.avif
index a50a2a13a2b..55eb9e2315b 100644
Binary files a/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/7e8d2f10-f1d6-4ec2-bac9-9db23499c9e1-0.avif and b/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/7e8d2f10-f1d6-4ec2-bac9-9db23499c9e1-0.avif differ
diff --git a/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/a0a5f1c8-5c31-4d9f-ae81-37bd67271d44-0.avif b/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/a0a5f1c8-5c31-4d9f-ae81-37bd67271d44-0.avif
index bac5059e943..1fce5821f8f 100644
Binary files a/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/a0a5f1c8-5c31-4d9f-ae81-37bd67271d44-0.avif and b/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/a0a5f1c8-5c31-4d9f-ae81-37bd67271d44-0.avif differ
diff --git a/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/ecd7762a-0.avif b/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/ecd7762a-0.avif
new file mode 100644
index 00000000000..f6d142aadb3
Binary files /dev/null and b/public/docs/images/tutorials/spin-chain-vqe/extracted-outputs/ecd7762a-0.avif differ
diff --git a/scripts/config/cspell/dictionaries/people.txt b/scripts/config/cspell/dictionaries/people.txt
index aaa3cb6be50..fca471ed3cc 100644
--- a/scripts/config/cspell/dictionaries/people.txt
+++ b/scripts/config/cspell/dictionaries/people.txt
@@ -62,6 +62,7 @@ Easwar
Edmonds
Eidenbenz
Eisert
+Emre
Epperly
Fangchun
Fock
@@ -189,6 +190,7 @@ Rossmannek
Ruchir
Rueschlikon
Saha
+Sahin
Saleem
Sangle
Sanjay