SQD i SKQD
W tym rozdziale przyjrzymy się, jak komputery kwantowe i klasyczne współpracują ze sobą, aby rozwiązać jedno z najważniejszych wyzwań nauki: dokładne szacowanie energii cząsteczek i materiałów.
Iskandar Sitdikov opisuje podejście algorytmiczne w poniższym filmie.
Hamiltonian
Kluczem do tego problemu jest operator matematyczny — Hamiltonian, który reprezentuje całkowitą energię układu. Na potrzeby obliczeń możemy myśleć o tym Hamiltonianie jak o dużej macierzy. Szukanych przez nas rozwiązań — konkretnie ground state układu — należy szukać wśród najniższych wartości własnych tej macierzy. Problem polega jednak na tym, że w praktycznych zastosowaniach macierz Hamiltonianu jest bardzo duża. Rośnie wykładniczo wraz z rozmiarem układu, szybko stając się zbyt wielka (, gdzie to liczba qubitów), aby nawet najpotężniejsze superkomputery mogły ją zapisać lub rozwiązać bezpośrednio.
Aby to obejść, stosujemy potężną strategię zwaną metodą podprzestrzeni. Zamiast atakować całą macierz, inteligentnie wybieramy mały, istotny wycinek — „podprzestrzeń" — o której sądzimy, że zawiera najważniejsze informacje dotyczące szukanego rozwiązania niskoenergetycznego.
Po zdefiniowaniu tej małej podprzestrzeni za pomocą zbioru stanów bazowych pełny Hamiltonian jest na nią rzutowany, tworząc nową, mniejszą macierz . Każdy element tej macierzy jest obliczany na podstawie stanów bazowych podprzestrzeni i oryginalnego Hamiltonianu jako . Ta mała macierz może następnie zostać łatwo zdiagonalizowana na komputerze klasycznym, a wynikające z tego wartości własne są naszymi szacowanymi energiami.
Jak można się domyślić, sukces całego tego podejścia w dużej mierze zależy od wyboru „dobrej" podprzestrzeni. Jeśli nasza podprzestrzeń nie reprezentuje dokładnie prawdziwego ground state, ostateczna odpowiedź będzie błędna. Tu właśnie z pomocą przychodzą komputery kwantowe: pozwalają nam przygotowywać i próbkować złożone stany kwantowe zaprojektowane do identyfikowania tych ważnych podprzestrzeni. W przypadku naprawdę ogromnych problemów — jak złożone struktury chemiczne czy miejsca wiązania — nawet rzutowana macierz może być trudna do zdiagonalizowania. Dlatego takie problemy idealnie nadają się do wykorzystania mocnych stron zarówno kwantowych, jak i klasycznych zasobów obliczeniowych.
W kolejnych sekcjach przyjrzymy się dwóm zaawansowanym algorytmom, SQD i SKQD, które wykorzystują mechanikę kwantową do znajdowania i konstruowania tych podprzestrzeni. Dla dogłębniejszego zapoznania się z tematem istnieje pełny kurs na IBM Quantum Learning poświęcony tym zagadnieniom. Na potrzeby tego kursu utrzymamy wyjaśnienia na wysokim poziomie ogólności.
Sample-based Quantum Diagonalization
Sample-based Quantum Diagonalization (SQD) to potężny algorytm wariacyjny implementujący metodę podprzestrzeni w sposób kwantowy. Unika kosztownych i skomplikowanych procedur, takich jak testy Hadamarda, wykorzystując komputer kwantowy do przygotowania stanu próbnego i próbkowania bitciągów, które definiują podprzestrzeń do klasycznej diagonalizacji.
Algorytm SQD można podzielić na następujące kroki:
Krok 1: Przygotowanie stanu ansatz
Niech będzie Hamiltonianem na qubitach. Choć prawdziwy ground state może być oparty na wszystkich stanach bazowych, SQD jest najbardziej efektywny w przypadkach, gdy ground state można dobrze aproksymować przez rzadką podprzestrzeń (wielomianowy zbiór bitciągów).
Aby zbudować tę podprzestrzeń, zaczynamy od stanu wejściowego , takiego jak stan Hartree-Focka (HF) w chemii. Następnie stosujemy sparametryzowany obwód kwantowy , znany jako ansatz.
Ten diagram ilustruje cel dobrego ansatzu. Ansatz przygotowuje stan kwantowy, którego nośnik (zbiór stanów bazowych, z których się składa) powinien idealnie mieć duże pokrycie z nośnikiem prawdziwego ground state. Ten obwód pozwala nam szybko rzutować ansatz na stany bazowe przestrzeni obliczeniowej, które zostaną następnie użyte w klasycznej diagonalizacji. Innymi słowy: nie musimy zgadywać ansatzu będącego ground state; wystarczy, że zawiera te same stany bazowe. Klasyczna diagonalizacja rzutowanego Hamiltonianu da nam superpozycję stanów bazowych najlepiej aproksymującą ground state.
Krok 2: Próbkowanie podprzestrzeni
Poprzez próbkowanie z obwodu przygotowanego przez ansatz otrzymujemy kolekcję bitciągów . Te bitciągi definiują bazę wybranej przez nas podprzestrzeni. Czas działania kwantowego w tym kroku zależy od głębokości obwodu i liczby pobranych próbek.
Krok 3: Rzutowanie i klasyczna diagonalizacja
Używając spróbkowanych bitciągów, rzutujemy Hamiltonian na podprzestrzeń przez nie rozpiętą. Dla każdej pary bitciągów klasycznie obliczamy element macierzy . Ponieważ operatory Pauliego są rzadkie, ten krok jest klasycznie efektywny dla fizycznych Hamiltonianów. Wynikowa mała macierz jest następnie diagonalizowana na procesorze klasycznym w celu oszacowania ground state i jego energii.
Krok 4: Optymalizacja ansatzu (opcjonalnie)
Proces można uczynić iteracyjnym. Traktując oszacowaną energię ground state jako funkcję kosztu, możemy optymalizować parametry obwodu () metodami takimi jak gradient descent, aby ulepszać ansatz, a co za tym idzie — aproksymację energii w kolejnej iteracji.
Key advantages of SQD
SQD oferuje kilka potężnych cech, które czynią go czołowym kandydatem do demonstrowania przewagi kwantowej:
- Duża odporność na szum: Załóżmy, że prawdziwy ground state jest oparty tylko na dwóch bitciągach. Jeśli zostaną one w ogóle spróbkowane — nawet jeśli ich pokrycie z naszym ansatzem jest małe — diagonalizacja przypisze im odpowiednie wagi i skutecznie zignoruje wszystkie inne zbędne, zaszumione bitciągi, które mogły zostać spróbkowane. Ta wbudowana filtracja sprawia, że SQD jest szczególnie odporny na szumy.
- Klasyczna weryfikowalność: W odróżnieniu od QPE czy VQA, SQD daje klasyczną aproksymację ground state. Oznacza to, że każdy, kto ma dostęp do listy bitciągów i ich wag, może samodzielnie przeliczyć i zweryfikować oszacowanie energii bezpośrednio na komputerze klasycznym.
SQD zostało już użyte do oszacowania energii dysocjacji ground state cząsteczki N oraz właściwości elektronowych klastrów [2Fe-2S] i [4Fe-4S] [2], z obwodami o rozmiarze do 77 qubitów i 10 570 bramek.
Check your understanding
Prawda czy fałsz: SQD można zastosować do układów chemicznych.
Odpowiedź:
Prawda
Check your understanding
Oznacz zbiór wszystkich stanów bazowych przestrzeni obliczeniowej tworzących twój ansatz jako . Oznacz zbiór wszystkich stanów bazowych przestrzeni obliczeniowej tworzących prawdziwy ground state twojego układu jako . Który z poniższych przypadków odpowiada „dobremu" ansatzowi? Zaznacz wszystkie poprawne odpowiedzi.
(a)
(b)
(c)
(d)
Odpowiedź:
(c) i (d)
SKQD (Sample-based Krylov Quantum Diagonalization)
Sample-based Krylov Quantum Diagonalization (SKQD) to kolejny potężny kwantowy algorytm oparty na próbkowaniu, który bazuje na zasadach SQD. Choć jego cel jest ten sam — znalezienie dobrej podprzestrzeni do diagonalizacji — SKQD stosuje bardziej ustrukturyzowaną metodę generowania bitciągów, szczególnie w przypadku problemów takich jak sieciowe Hamiltoniany.
Podstawowa idea SKQD polega na tym, że zamiast optymalizować sparametryzowany obwód w celu znalezienia dobrego ansatzu, można w dowiedziony sposób zbiegać do stanu podstawowego poprzez próbkowanie ze zbioru stanów wygenerowanych przez naturalną ewolucję czasową samego układu — podprzestrzeń Krylov. Algorytm SKQD można rozbić na następujące kroki:
Krok 1: Zbuduj podprzestrzeń Krylov za pomocą ewolucji czasowej
Proces zaczyna się od stanu początkowego Co ważne, nie jest potrzebne, by ten stan początkowy miał „dobre" pokrycie ze stanem podstawowym. Wystarczy, że jest „wielomianowo duży", czyli opisany wielomianem rozmiaru układu. Sam algorytm będzie następnie przybliżał stan coraz bliżej stanu podstawowego układu. SKQD stosuje operator ewolucji czasowej, , dla różnych długości czasu. W ten sposób powstaje zbiór różnych stanów kwantowych, zdefiniowanych jako:
Ten zbiór stanów po ewolucji czasowej tworzy bazę Krylov. Ten krok jest szczególnie skuteczny w przypadku sieciowych Hamiltonianów, w których liczba wyrazów Hamiltonianu nie jest duża. W przypadku problemów chemicznych ewolucja czasowa może prowadzić do bardzo głębokich obwodów, dlatego w takich przypadkach zaleca się stosowanie SQD.
Krok 2: Próbkuj ze stanów bazy Krylov
Następnie ze wszystkich różnych stanów () przygotowanych w poprzednim kroku zbierane są próbki bitciągów. Wszystkie te bitciągi są następnie łączone, tworząc bazę podprzestrzeni.
Krok 3: Rzutuj i diagonalizuj klasycznie
Ten krok jest identyczny jak w SQD. Zebrane bitciągi są używane do rzutowania pełnego Hamiltonianu na rozpiętą przez nie podprzestrzeń. Wynikająca z tego mała macierz, , jest następnie diagonalizowana na klasycznym komputerze w celu wyznaczenia energii stanu podstawowego.
Key advantages and guarantees of SKQD
Ustrukturyzowane podejście SKQD zapewnia wyjątkowe korzyści:
-
Dowiedziona zbieżność: kluczową zaletą SKQD jest teoretyczna gwarancja zbieżności w określonych, dobrze zdefiniowanych warunkach. Jeśli prawdziwy stan podstawowy jest rzadki (może być dobrze aproksymowany przez wielomianową liczbę bitciągów), a przerwa energetyczna do pierwszego wzbudzonego stanu nie jest zbyt mała, dowiedziono, że metoda działa efektywnie. W tych warunkach SKQD gwarantuje znalezienie kluczowych bitciągów składających się na stan podstawowy i może aproksymować energię stanu podstawowego z dużą dokładnością. Wymaga to jedynie wielomianowej liczby eksperymentów kwantowych i ujęć. Gwarancja ta stawia podejście oparte na próbkowaniu na solidnych teoretycznych podstawach, podobnie do uznanych metod takich jak kwantowe szacowanie faz.
-
Wspólne zalety z SQD: podobnie jak SQD, SKQD posiada również właściwość odporności na szumy. Innymi słowy, dopóki w zbiorze próbkowanych bitciągów znajdują się wszystkie dobre bitciągi, diagonalizacja przypisuje niemal zerową wagę nieprawidłowym bitciągom, co sprawia, że procedura jest odporna na szumy. Ponadto, ponieważ rozwiązanie jest wytwarzane przez klasyczny HPC, energia rozwiązania jest klasycznie weryfikowalna.
W eksperymentach SKQD był stosowany z nawet 70 kubitami i tysiącami bramek do badania stanu podstawowego złożonych modeli Andersona z 4 zanieczyszczeniami, osiągając doskonałą zgodność z najnowocześniejszymi klasycznymi metodami, takimi jak DMRG.[1]
Check your understanding
Która część algorytmu SKQD sprawia, że nadaje się on lepiej do problemów fizycznych, takich jak sieciowe układy spinowe, niż do problemów chemicznych? Dlaczego?
Odpowiedź:
Ewolucja czasowa wymaga obwodów Trottera, które są bardzo głębokie dla Hamiltonianów skomplikowanych i nierzadkich. Oddziaływania sieciowe spinów są opisywane przez macierze spinowe, odpowiadające macierzom Pauli. Hamiltoniany układów sieciowych spinów mają więc tendencję do bardziej zwartego wyrażania się w macierzach Pauli, szczególnie te z oddziaływaniami najbliższych sąsiadów.
SQD i SKQD jako obliczenia heterogeniczne
Aby zebrać wszystko razem, możemy przedstawić algorytmy oparte na próbkowaniu jako kombinację różnych modeli programowania na zestawie heterogenicznych zasobów. Na przykład, możemy przedstawić nasz algorytm jako przepływ pracy składający się z zadań.
Ten rysunek ilustruje podstawowy czteroetapowy przepływ pracy. Na początku będziemy mieli zadanie przygotowania obwodu kwantowego, który pokrywa się z naszym stanem docelowym, a następnie zadanie transpilacji, które do wykonania wymaga jedynie zasobów klasycznych. Następnie znajduje się zadanie wykorzystujące prymitywy do wykonania naszego obwodu kwantowego, które wymaga zasobów kwantowych. Wreszcie, mamy zadanie post-processingu, które samo w sobie może być równoległym algorytmem diagonalizacji uruchomionym na wielu węzłach.
Dodatkowo, możemy chcieć uruchomić jeden z tych algorytmów wiele razy, zmieniając nasz ansatz, lub możemy chcieć uruchomić je całkowicie równolegle z różnymi populacjami.
Jak pokazano powyżej, możesz uruchamiać wiele przepływów pracy jednocześnie, wykonując następujące czynności:
- Zmienianie parametrów lub struktury ansatzu w celu znalezienia najbardziej efektywnego.
- Rozpoczynanie od różnych stanów początkowych lub konfiguracji ("populacji"), aby uniknąć minimów lokalnych i zapewnić bardziej solidny wynik.
To wielowarstwowe podejście, łączące heterogeniczność opartą na zadaniach z równoległością na poziomie przepływu pracy, jest kluczem do odblokowania pełnego potencjału tych algorytmów.
Praktyka programowania
Przećwiczmy algorytm SKQD, demonstrując heterogeniczny przepływ pracy opisany wcześniej. Proces jest podzielony na cztery odrębne etapy, każdy z własnym skryptem Pythona i odpowiadającym mu skryptem powłoki do zlecania zadań.
Mapowanie (mapping.py i mapping.sh)
Pierwszym krokiem w naszym przepływie pracy jest zdefiniowanie problemu fizycznego i zmapowanie go na zestaw obwodów kwantowych.
Plik mapping.py definiuje parametry dla konkretnego problemu fizycznego — w tym przypadku modelu domieszkowego Andersona z siedmioma miejscami kąpieli (n_bath = 7). Konstruuje on całki jednociałowe (h1e) i dwuciałowe (h2e), które reprezentują Hamiltonian układu.
...
n_bath = 7 # number of bath sites
...
# One body matrix elements in the "position" basis
h1e = -t * np.diag(np.ones(n_bath), k=1) - t * np.diag(np.ones(n_bath), k=-1)
h1e[impurity_index, impurity_index + 1] = -V
h1e[impurity_index + 1, impurity_index] = -V
h1e[impurity_index, impurity_index] = eps
# Two body matrix elements in the "position" basis
h2e = np.zeros((n_bath + 1, n_bath + 1, n_bath + 1, n_bath + 1))
h2e[impurity_index, impurity_index, impurity_index, impurity_index] = U
...
# The one-body time evolution
free_fermion_evolution = ffsim.qiskit.OrbitalRotationJW(n_modes, Utar)
# The two-body time evolution
def append_diagonal_evolution(dt, U, impurity_qubit, num_orb, q_circuit):
"""Append two-body time evolution to a quantum circuit."""
if U != 0:
q_circuit.append(
CPhaseGate(-dt / 2 * U),
[impurity_qubit, impurity_qubit + num_orb],
)
Następnie generuje on obwody kwantowe wymagane przez algorytm SKQD. Zaczyna od utworzenia stanu początkowego (initial_state), a następnie stosuje operatory ewolucji w czasie dla różnej liczby kroków (d = 8), aby wygenerować różne stany bazowe Kryłowa, .
# The reference state
def initial_state(q_circuit, norb, nocc):
"""Prepare an initial state."""
for i in range(nocc):
q_circuit.append(XGate(), [i])
q_circuit.append(XGate(), [norb + i])
rot = XXPlusYYGate(np.pi / 2, -np.pi / 2)
for i in range(3):
for j in range(nocc - i - 1, nocc + i, 2):
q_circuit.append(rot, [j, j + 1])
q_circuit.append(rot, [norb + j, norb + j + 1])
q_circuit.append(rot, [j + 1, j + 2])
q_circuit.append(rot, [norb + j + 1, norb + j + 2])
...
# Generate the initial state
qubits = QuantumRegister(2 * n_modes, name="q")
init_state = QuantumCircuit(qubits)
initial_state(init_state, n_modes, n_modes // 2)
...
d = 8 # Number of Krylov basis states
circuits = []
for i in range(d):
circ = init_state.copy()
circuits.append(circ)
for _ in range(i):
append_diagonal_evolution(dt, U, impurity_index, n_modes, circ)
circ.append(free_fermion_evolution, qubits)
append_diagonal_evolution(dt, U, impurity_index, n_modes, circ)
circ.measure_all()
print(circuits[0].draw(scale=0.4, fold=-1))
Skrypt zapisuje listę 8 wygenerowanych obwodów (każdy z dołączonymi pomiarami) do pliku o nazwie circuits.qpy.
Plik mapping.sh to skrypt wsadowy Slurm używany do zlecania zadania mapping.py. Ponieważ jest to obliczenie klasyczne, żąda on zasobów ze standardowej partycji CPU (--partition=normal).
#!/bin/bash
#
#SBATCH --job-name=sqd-mapping
#SBATCH --output=sqd-mapping.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=normal
srun python /data/ch4/sqd/mapping.py
Optymalizacja (optimization.py i optimization.sh)
Gdy mamy już nasze obwody, muszą one zostać zoptymalizowane i skompilowane, aby efektywnie działały na docelowym sprzęcie kwantowym.
W pliku optimization.py ten skrypt najpierw ładuje plik circuits.qpy utworzony na etapie mapowania i pobiera informacje o zasobach kwantowych za pomocą QRMI(), menedżera zasobów kwantowych. Następnie używa funkcji generate_preset_pass_manager z Qiskit z wysokim poziomem optymalizacji (optimization_level=3), aby przekonwertować abstrakcyjne, logiczne obwody na obwody zgodne z architekturą zestawu instrukcji (ISA circuits). Proces ten przepisuje obwody przy użyciu natywnych bramek sprzętu i optymalizuje je, aby zmniejszyć głębokość i zminimalizować błędy.
...
qrmi = QRMI()
resources = qrmi.resources()
quantum_resource = resources[0]
target = quantum_resource.target
pass_manager = generate_preset_pass_manager(
optimization_level=3,
target=target
)
isa_circuits = pass_manager.run(circuits)
Przetranspilowane, gotowe do uruchomienia na sprzęcie obwody są zapisywane do nowego pliku isa_circuits.qpy.
Podobnie jak skrypt mapowania, to zadanie Slurm również działa na klasycznej partycji CPU (--partition=normal), ponieważ transpilacja jest zadaniem klasycznym.
#!/bin/bash
#
#SBATCH --job-name=sqd-mapping
#SBATCH --output=sqd-mapping.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=normal
srun python /data/ch4/sqd/mapping.py
Wykonanie (execution.py i execution.sh)
To jedyny etap, na którym używany jest komputer kwantowy. Tutaj wykonujemy zoptymalizowane obwody i zbieramy próbki pomiarów.
Plik execution.py ładuje zoptymalizowany plik isa_circuits.qpy, a następnie inicjalizuje prymityw SamplerV2, który jest połączony z zasobem kwantowym. Następnie wywołuje sampler.run(), aby wykonać obwody na QPU dla określonej liczby strzałów (shots=500).
...
qrmi = QRMI()
resources = qrmi.resources()
quantum_resource = resources[0]
# Sample from the circuits
noisy_sampler = Sampler(quantum_resource)
job = noisy_sampler.run(isa_circuits, shots=500)
Na koniec wykonania zmierzone wyniki (ciągi bitów) ze wszystkich obwodów są zbierane i łączone, a ich liczności są zapisywane do pliku counts.json.
Skrypt Slurm execution.sh różni się od pozostałych na tym etapie. Wymaga uruchomienia na partycji kwantowej (--partition=quantum) i konkretnie żąda jednego QPU (--gres=qpu:1).
#!/bin/bash
#
#SBATCH --job-name=sqd-execution
#SBATCH --output=sqd-execution.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum
#SBATCH --gres=qpu:1
srun python /data/ch4/sqd/execution.py
Przetwarzanie końcowe (postprocessing.py i postprocessing.sh)
W ostatnim kroku wracamy do komputera klasycznego, aby przeanalizować dane z eksperymentu kwantowego i obliczyć końcowy wynik: energię stanu podstawowego naszego docelowego układu.
Program postprocessing.py najpierw odczytuje plik counts.json zawierający wyniki pomiarów. Następnie rekonstruuje Hamiltonian modelu Andersona (używając tych samych parametrów co w mapping.py). Potem przekazuje zmierzone bitstringi oraz definicję Hamiltonianu do funkcji diagonalize_fermionic_hamiltonian. Funkcja ta realizuje główną logikę SKQD: wykorzystuje bitstringi do skonstruowania zrzutowanego Hamiltonianu i diagonalizuje go, aby znaleźć energię stanu podstawowego.
...
def callback(results: list[SCIResult]):
result_history.append(results)
iteration = len(result_history)
print(f"Iteration {iteration}")
for i, result in enumerate(results):
print(f"\tSubsample {i}")
print(f"\t\tEnergy: {result.energy}")
print(f"\t\tSubspace dimension: {np.prod(result.sci_state.amplitudes.shape)}")
rng = np.random.default_rng(24)
result = diagonalize_fermionic_hamiltonian(
h1e,
h2e,
bit_array,
samples_per_batch=300,
norb=n_modes,
nelec=nelec,
num_batches=3,
max_iterations=10,
symmetrize_spin=True,
callback=callback,
seed=rng,
)
Na koniec program wypisuje obliczoną energię SKQD i porównuje ją ze znaną energią dokładną dla tego problemu, pokazując końcowy błąd bezwzględny obliczeń.
Końcowy skrypt zadania uruchamia się na partycji klasycznej (--partition=normal), ponieważ cała analiza jest klasyczna. W przypadku dużych podprzestrzeni ten krok może wymagać większych klasycznych zasobów HPC.
#!/bin/bash
#
#SBATCH --job-name=sqd-postprocessing
#SBATCH --output=sqd-postprocessing.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=normal
srun python /data/ch4/sqd/postprocessing.py
Podsumowanie
I to wszystko! Omówiliśmy kilka koncepcji i przykładów, które mogą pomóc Ci rozpocząć zarządzanie złożonymi programami hybrydowymi. Oczywiście to dopiero początek tego, co można zrobić dzięki połączeniu kwantowych i klasycznych zasobów HPC.
Aby poznać więcej przypadków użycia i algorytmów, przeglądaj naszą dokumentację oraz samouczki na platformie IBM Quantum Platform, a także koniecznie odwiedź zasoby udostępnione w następnej lekcji, aby uzyskać więcej informacji o algorytmach i oprogramowaniu zarówno dla naukowców obliczeniowych, jak i administratorów centrów danych.
Bibliografia
[1] Quantum-Centric Algorithm for Sample-Based Krylov Diagonalization. https://arxiv.org/abs/2501.09702
[2] Chemistry beyond the scale of exact diagonalization on a quantum-centric supercomputer. https://www.science.org/doi/10.1126/sciadv.adu9991