주 콘텐츠로 건너뛰기

컴퓨팅 리소스와 리소스 관리

리소스 모델과 고전 리소스

이 섹션에서는 노트북부터 슈퍼컴퓨터까지 모든 컴퓨팅 환경에 적용할 수 있는 사고 체계를 소개합니다. 이 섹션을 마치면 컴퓨팅 환경의 기본 구성 요소와 그 상호 관계를 이해하게 됩니다. 이 모든 내용은 Iskandar Sitdikov가 아래 동영상에서 설명합니다.

리소스 모델

모든 고전 컴퓨팅 환경은 애플리케이션을 효율적으로 실행하기 위해 함께 동작하는 여러 상호 연관된 리소스로 구성됩니다. 주요 리소스는 일반적으로 다음을 포함합니다.

  • CPU(중앙 처리 장치): CPU는 프로그램 명령을 해석하고 실행하는 핵심 처리 장치입니다. 논리, 산술, 제어 연산을 처리하며 시스템의 "두뇌" 역할을 합니다.

  • CPU 캐시(L1, L2, L3): 시스템에서 가장 빠른 메모리로, CPU 코어 내부나 매우 가까운 위치에 내장되어 있습니다. CPU가 즉시 필요로 하는 소량의 데이터와 명령어를 저장합니다. 각 레벨(L1, L2, L3)은 트레이드오프를 나타냅니다. L1은 가장 작고 빠르며 L3는 가장 크고 느리지만, 여전히 RAM보다 몇 자릿수 빠릅니다.

  • RAM(랜덤 액세스 메모리): 프로그램 명령어와 현재 사용 중인 데이터를 위한 크고 임시적인 저장 공간을 제공하는 휘발성 메모리입니다. CPU가 느린 저장 장치에 지속적으로 의존하지 않고 실행 중에 필요한 정보에 빠르게 접근할 수 있도록 보장합니다.

  • 스토리지(로컬 및 네트워크 기반): 스토리지는 시스템 전원이 꺼진 후에도 데이터와 소프트웨어를 유지하며, 대용량 데이터셋과 애플리케이션을 위한 장기적인 영속성을 제공합니다. 고성능 컴퓨팅에서 스토리지 솔루션은 속도와 신뢰성을 갖추고 방대한 양의 과학적 또는 분석 데이터를 처리해야 합니다. 로컬 스토리지에는 SSD(솔리드 스테이트 드라이브)와 HDD(하드 디스크 드라이브)가 포함되며, 낮은 레이턴시와 높은 처리량 덕분에 SSD가 선호됩니다. 대규모 데이터 처리를 위해 병렬 파일 시스템, 공유 네트워크 스토리지, 객체 기반 시스템은 여러 컴퓨팅 노드에 걸쳐 빠른 액세스를 가능하게 하며, 클라우드 및 아카이브 스토리지 계층은 장기 보존 및 확장성을 지원합니다.

  • GPU(그래픽 처리 장치): 처음에는 그래픽 렌더링을 위해 설계되었지만, 현대의 GPU는 강력한 병렬 프로세서입니다. 딥러닝, 물리 시뮬레이션, 빅데이터 분석처럼 많은 동시 계산이 필요한 작업 처리에 널리 사용됩니다. GPU가 CPU를 대체하는 것이 아님을 주목하는 것이 중요합니다. CPU는 상위 수준의 프로그램 로직을 지시하고, GPU는 고도로 병렬화된 단계를 가속화합니다.

  • 연결/버스: CPU, 메모리, 스토리지, 주변 장치를 연결하는 통신 경로입니다. 버스는 시스템 구성 요소 간의 데이터 전송과 조율을 가능하게 하여 컴퓨팅 환경 전반에 걸쳐 원활한 통신을 보장합니다. HPC 시스템에서는 CPU, GPU, 스토리지 장치와 같은 구성 요소들이 고속 인터커넥트로 연결되어 빠른 데이터 교환을 가능하게 합니다. GPU는 일반적으로 효율적인 통신을 위한 다중 데이터 레인을 갖춘 표준 인터페이스인 PCIe를 통해 시스템에 연결됩니다. 더 높은 성능을 위해 NVLink는 GPU 간 또는 GPU와 CPU 간에 직접적인 고대역폭 연결을 제공하여 레이턴시를 줄이고 병렬 작업을 가속화합니다.

  • 파일시스템: 파일시스템은 스토리지 장치의 데이터를 구성합니다. 파일을 저장, 검색, 관리하기 위한 구조를 제공하여 프로그램과 사용자가 일관되고 논리적인 방식으로 정보에 접근할 수 있게 합니다.

각 리소스 유형에는 자체적인 성능 관련 측정 단위가 있습니다. 예를 들어, CPU는 일반적으로 "코어" 수와 "클럭 속도"로 측정됩니다. 노트북을 구매할 때 사양에는 보통 코어 수가 포함되어 있습니다. 데이터 센터의 컴퓨팅 노드에도 유사한 개념이 적용되며, 각 노드는 특정 수의 코어와 연관됩니다. CPU, GPU, 심지어 QPU를 포함하는 여러 리소스 유형을 포함하는 컴퓨팅 환경을 __이기종 컴퓨팅 환경__이라고 합니다. 이러한 설정은 각 프로세서 유형의 강점을 활용하여 다양한 워크로드를 보다 효율적으로 처리합니다. 예를 들어, CPU는 일반 작업에, GPU는 병렬 처리에 사용됩니다. 리소스 관리 및 스케줄링 - 특히 이기종 컴퓨팅 환경 - 의 맥락에서는 여기에 설명된 것 외에 추가 측정 단위가 필요할 수 있습니다.

메모리의 경우 측정 단위는 메가/기가/테라바이트입니다.

그래픽 카드 및 기타 가속기의 경우 측정 단위는 맥락에 따라 다릅니다. 실제 컴퓨팅 성능은 처리 코어 수, 메모리 크기, 메모리 대역폭과 같은 세밀한 지표로 측정되지만, 클러스터 리소스나 작업 스케줄링에 대한 고수준 논의에서 GPU 및 유사한 가속기는 할당된 전체 장치 수(예: GPU 3개)로 장치 수준에서 수량화할 수 있습니다.

네트워크/연결/버스는 컴퓨팅 구성 요소 간 데이터 전송 속도를 결정하기 때문에 모든 컴퓨팅 인프라의 중요한 측면입니다. LPU에서 CPU 캐시, RAM, PCI 카드, 네트워크 연결 장치에 이르기까지 모든 것이 통신이며, HPC에 최적화된 알고리즘을 설계하려면 이에 대한 정확한 멘탈 모델을 갖추는 것이 중요합니다.

각 컴퓨팅 노드에 여러 유형의 리소스가 포함될 수 있음을 보여주는 이미지.

고전 리소스 확장

고성능 컴퓨팅(HPC)은 이러한 고전 리소스를 확장하여 더 빠른 처리 시간을 달성하거나 동시에 처리할 수 있는 데이터를 늘리는 것을 목표로 합니다(예: 탐색 가능한 솔루션 공간의 크기 확대). 이는 다음을 통해 달성할 수 있습니다.

  • 수직 확장: 개별 리소스의 성능을 향상시키는 것으로, 예를 들어 더 강력한 CPU를 사용하거나 하나의 물리적 노드 내에서 메모리를 추가하는 방법입니다. 여기서 노드는 여러 컴퓨팅 리소스를 내부에 캡슐화하는 컴퓨팅 클러스터의 단위입니다.

  • 수평 확장: 여러 CPU나 GPU 등 리소스를 추가하여 하나의 노드에서 또는 더 일반적으로는 여러 노드에서 함께 작동하게 함으로써 분산 계산을 가능하게 하는 방법입니다.

단일 노드 내에 메모리와 같은 리소스를 더 많이 배치하는 수직 확장과, 다양한 리소스 유형을 포함한 연결된 노드 수를 늘리는 수평 확장을 보여주는 이미지.

이 섹션의 일부 확장 개념은 다음 섹션인 양자 컴퓨팅 리소스에도 적용됩니다. 양자 리소스의 일부 다른 측면은 새로운 방식으로 정량화됩니다.

이해도 확인

위의 설명을 활용하여 수직 확장과 수평 확장의 각 장단점을 추론해 보세요.

답변:

정답이 여러 가지일 수 있습니다. 수직 확장은 예측 가능한 워크로드에 고정된 양의 리소스가 필요한 경우 특히 더 단순합니다. 그러나 수평 확장에서처럼 컴퓨팅의 기본 단위를 쉽게 분해할 수 없기 때문에 업그레이드 비용이 더 많이 들 수 있습니다. 수평 확장은 관리가 더 복잡하고 때로는 노드 간 연결과 관련된 어려움이나 레이턴시가 발생하기도 합니다. 그러나 다양한 리소스 요구 사항에 훨씬 더 잘 적응하고 업그레이드가 필요할 때 모듈식으로 처리할 수 있습니다.

새로운 유형의 리소스: QPU (양자 처리 장치)

이 섹션에서는 새로운 유형의 리소스인 양자 리소스를 소개하고, 그 정의와 측정 단위, 그리고 고전 인프라와의 연결 방식을 살펴봅니다.

QPU의 정의

  • 양자 처리 장치(QPU): QPU는 실행 가능한 양자 명령어 집합, 즉 양자 Circuit을 받아들이고 정확한 결과를 반환하는 데 필요한 모든 하드웨어를 포함합니다.

즉, QPU에는 하나 이상의 양자 칩(예: Heron), 희석 냉각기 내의 다양한 추가 부품(양자 증폭기, 제어 전자 장치 등), 그리고 명령어와 파형을 메모리에 저장하고, 결과를 누적하며, 향후 오류 정정 디코딩과 같은 작업에 필요한 고전 컴퓨팅이 포함됩니다. 희석 냉각기는 이러한 작업을 수행하는 데 필수적이지만, 동일한 냉각기에 여러 QPU가 존재할 수 있는 경우를 허용하기 위해 QPU의 정의에서 제외합니다.

  • 양자 컴퓨터: 양자 컴퓨터는 QPU와 런타임 환경을 호스팅하는 고전 컴퓨팅으로 구성됩니다.

  • 런타임 환경: 프로그램 실행을 가능하게 하는 하드웨어와 소프트웨어의 조합입니다.

양자 Circuit의 레이어

고전 컴퓨팅과 양자 컴퓨팅 모두에서 프로세스는 순차적으로 또는 병렬로 실행될 수 있습니다. Qubit은 고전적인 비트에 비해 풍부한 상태 공간을 가지기 때문에, 하나의 Qubit에 여러 단일 Qubit Gate가 순차적으로 실행되는 것(예: R_x Gate 다음에 R_z Gate)이 유의미한 경우가 있습니다. 양자 컴퓨팅에서 Qubit 간의 얽힘은 매우 중요하므로, 양자 Circuit에서 많은 Qubit에 걸쳐 얽힘 Gate 집합이 작동하는 것이 일반적입니다. 이러한 요소들로 인해 양자 Circuit에서 개별 Gate 연산 수준의 병렬 실행 가능한 프로세스를 식별하는 것이 일반적입니다. 고전 컴퓨팅에서도 비트 수준의 병렬 처리가 가능하지만 Gate 수준에서는 덜 일반적으로 고려되며, 더 큰 규모의 병렬 및 순차 프로세스를 언급하는 것이 더 흔합니다.

양자 컴퓨팅에서는 동시에 실행될 수 있는 Gate의 "레이어"를 언급합니다. 많은 응용 프로그램에서 모든 Qubit에 회전 집합을 수행한 후 Qubit 쌍 간의 얽힘 Gate를 수행하는 것이 유용합니다. 이러한 맥락에서 "회전 레이어"(R_x, R_y, R_z와 같은 Gate로 구성된 레이어)와 "얽힘 레이어"(CNOT Gate가 포함된 레이어)를 언급합니다. Circuit의 레이어 수가 "Circuit 깊이"이며, 깊이가 클수록 더 많은 레이어의 누적 노이즈와 오류가 발생하므로 중요한 측정 지표입니다.

배리어를 사용해 레이어를 정렬하지 않으면 Gate 레이어를 시각적으로 식별하기 어려울 수 있습니다. Qiskit에서 배리어는 양자 Circuit의 명령어로, 시각적 구분자이자 컴파일 시의 제약으로 작동합니다. Circuit을 그릴 때와 실행할 때 모두 배리어를 넘어 Gate가 이동하지 않습니다. 이는 특정 오류 유형을 억제하기 위해 의도적으로 항등식으로 단순화되는 Gate를 구현하는 동적 디커플링과 같은 맥락에서 중요할 수 있습니다. 동적 디커플링에 대한 자세한 내용은 이 가이드를 참조하세요. 배리어의 시각적 효과를 확인하려면, 동일한 Circuit의 두 이미지를 비교해 보세요. 첫 번째는 배리어 없이, 두 번째는 레이어 정렬을 강제하는 배리어가 있는 경우입니다.

레이어 정렬을 강제하는 배리어가 없는 4-Qubit 양자 Circuit; Gate가 다소 무작위로 정렬되어 있습니다.

레이어 정렬을 강제하는 배리어가 있는 4-Qubit 양자 Circuit. 이제 레이어를 세는 것이 훨씬 쉽습니다.

이것은 동일한 Circuit으로 레이어 수도 같습니다. 그러나 두 번째에서는 정렬 덕분에 Circuit이 다음을 포함한다는 것을 쉽게 알 수 있습니다.

  • 두 개의 회전 레이어: Y축 기준 π/5\pi/5 회전 하나, Z축 기준 π/4\pi/4 회전 하나.
  • 세 개의 얽힘 레이어. 각 CNOT을 독립적인 "레이어"로 볼 수 있는데, 이는 논리 연산을 변경하지 않고서는 CNOT들을 병렬로 재배열할 수 없기 때문입니다.
  • 두 개의 추가 회전 레이어: Y축 기준 π/3\pi/3 회전 하나, Z축 기준 π/2\pi/2 회전 하나.
  • 두 개의 추가 얽힘 레이어. 이번에는 첫 번째 레이어가 첫 번째 얽힘 레이어 집합보다 약간 더 병렬화되어 있습니다.

각 Circuit의 깊이는 9입니다.

측정 단위

양자 컴퓨팅에서 양자 시스템의 성능은 일반적으로 규모(scale), 품질(quality), 속도(speed)라는 세 가지 핵심 성능 지표로 평가됩니다. 이 지표들은 양자 장치의 계산 잠재력을 설명할 뿐만 아니라, 실제 응용에서 리소스가 어떻게 관리되고 스케줄링되는지를 알려줍니다.

  • 규모(Scale)는 시스템 내 양자 비트(Qubit)의 수를 의미하며, 장치가 보유할 수 있는 양자 정보의 양을 나타냅니다. 리소스 관리 측면에서 이는 주어진 양자 작업을 실행하는 데 필요한 Qubit 수, 즉 Circuit 너비에 직접적인 영향을 미칩니다. 양자 장치는 할당된 작업을 지원하기에 충분한 Qubit을 보유해야 합니다.

  • 품질(Quality)은 양자 연산이 얼마나 정확하게 수행되는지를 설명합니다. 이는 종종 레이어 충실도(layer fidelity)로 정량화되는데, 이는 모든 Qubit에 걸쳐 전체 양자 Gate 레이어를 실행하는 정확도를 측정합니다. 스케줄링 관점에서 높은 충실도는 더 깊은 Circuit을 안정적으로 실행할 수 있게 하여, 오류 완화 또는 작업 분해의 필요성에 영향을 줍니다.

  • 속도(Speed)는 CLOPS(Circuit Layer Operations Per Second)로 측정되며, 시스템이 초당 실행할 수 있는 양자 연산 레이어 수를 나타냅니다. 이는 작업 실행의 처리량과 지연 시간에 영향을 미치며, 양자 장치가 주어진 작업 부하를 완료하는 데 얼마나 빠른지를 파악하는 데 도움이 됩니다. 이 속도는 양자 컴퓨터에서 특히 중요한데, 이는 Qubit이 고전적인 대응물보다 훨씬 더 큰 정도로 노이즈와 오류에 영향을 받기 때문입니다. 유용한 방식으로 양자 정보를 유지할 수 있는 시간은 __결맞음 시간(coherence time)__으로 설명되며, Heron r3 프로세서의 경우 일반적으로 200-300 μs\mu\text{s} 정도입니다.

양자 지표와 고전 지표의 차이

CLOPS를 FLOPS의 느슨한 양자 유사물로 생각할 수 있지만, 몇 가지 중요한 차이점이 있습니다. CLOPS는 양자 프로세서가 양자 Circuit, 특히 Circuit 내의 연산 레이어를 실행하는 속도를 측정하며, 여기에는 Circuit 실행에 필요한 양자 연산과 고전 컴퓨팅이 모두 포함됩니다. IBM Quantum이 순수하게 고전 프로세서의 부동 소수점 산술 용량을 측정하는 FLOPS와 달리, 양자 실행 시간과 Circuit 업데이트에 필요한 실시간 고전 처리를 포함하는 양자 컴퓨터 실행 속도의 종합적인 측정 지표로 개발했습니다.

CLOPS는 기존 하드웨어에서 벤치마킹할 수 있는 측정 가능한 성능 지표를 제공합니다. IBM Quantum은 CLOPS를 사용하여 다양한 양자 프로세서를 벤치마킹했으며, 그 값은 IBM Quantum Platform의 컴퓨팅 리소스 페이지에서 확인할 수 있습니다. CLOPS 값은 하드웨어 성능, Gate 속도, 고전 처리 속도, 그리고 이들의 통합에 따라 달라집니다.

Qubit 수는 주어진 QPU에 대해 고정된 수입니다. CLOPS와 품질은 정기적인 교정 및 유지 관리에 따라 달라지며, 단일 QPU에서도 시간이 지남에 따라 약간씩 변동될 수 있습니다.

이러한 지표들은 양자 시스템의 할당 및 스케줄링 방식을 안내합니다. 많은 경우 전체 양자 시스템은 단일 단위로 처리됩니다. 그러나 작업이 Qubit 수, Circuit 깊이, 또는 실행 속도 면에서 한 단위의 용량을 초과하는 경우, Circuit 커팅/니팅과 같은 기법을 사용할 수 있습니다. Circuit 커팅은 큰 양자 작업을 더 작고 관리 가능한 하위 작업으로 분해하여 여러 양자 칩에 분산시키는 프로세스로, 하드웨어 한계에도 불구하고 확장 가능한 양자 계산을 가능하게 합니다. Circuit 니팅은 Circuit 커팅 이후에 오는 프로세스, 즉 더 작은 하위 Circuit의 결과를 다시 "니팅(결합)"하는 고전 후처리 단계를 말합니다.

양자 컴퓨터에는 RAM이나 GPU 메모리와 같은 영구적이고 주소 지정 가능한 저장소라는 의미의 전통적인 메모리가 없습니다. 고전 컴퓨팅 리소스는 메모리에 저장된 이산 비트를 가지고 있어, 계산 중에 데이터를 저장하고 가져오며 재사용할 수 있습니다. 양자 리소스는 고전적인 의미에서 메모리를 저장하지 않는 Qubit을 사용합니다. 대신 Qubit은 0과 1의 중첩을 동시에 나타내는 양자 상태로 존재하여 상태 공간에서 지수적 병렬성을 가능하게 합니다. 그러나 Qubit 상태는 불안정하며 양자 상태를 붕괴시키지 않고 중간 단계에서 복제하거나 결정론적으로 읽을 수 없으므로, 계산 중 지속적인 메모리와 같은 동작이 존재하지 않습니다. Qubit은 실행 전체에 걸쳐 결맞음 상태를 유지해야 하며, "메모리"는 본질적으로 양자 상태 자체입니다. 고전 메모리는 내부 양자 메모리로서가 아니라 양자 프로세서와 함께만 사용될 수 있습니다. 이는 중요한 함의를 가집니다. 고전 컴퓨팅 리소스는 중간 결과를 자유롭게 재사용하고 저장할 수 있지만, 양자 리소스는 계산을 방해하는 측정 없이는 이를 수행할 수 없습니다.

고전 인프라와의 연결

QPU는 소프트웨어 개발자가 프로그래밍 방식으로 QPU와 상호 작용할 수 있게 하는 네트워크와 다양한 애플리케이션 프로그래밍 인터페이스(API)를 통해 고전 인프라에 연결될 수 있습니다. 이러한 API는 일반적으로 소프트웨어 개발 키트(SDK)와 라이브러리(Qiskit 등) 뒤에 숨겨져 있으며, 프로그래밍 추상화(3장 프로그래밍 모델에서 다룰 Qiskit Primitives 등) 형태로 계산 과학자에게 제공됩니다.

양자 리소스와 고전 리소스의 긴밀한(tight) 통합과 느슨한(loose) 통합을 구별하는 것이 중요합니다. 현재 QPU는 고전 컴퓨팅 리소스와 같은 노드에 있지 않습니다. 실제로 QPU는 현재 PCIe를 통해 연결되지 않고 네트워크를 통해 연결됩니다. 이는 향후 변경될 수 있지만, QPU와 고전 컴퓨팅 리소스에 최적인 환경 조건과 관련된 엔지니어링 과제가 있습니다.

양자 리소스의 확장

양자 리소스의 확장도 수직 및 수평으로 분류할 수 있습니다.

  • 수직 확장은 칩당 Qubit 수를 늘리거나 장치의 충실도를 향상시키는 것입니다.
  • 수평 확장은 칩을 커플러나 고전 상호 연결로 연결하는 것입니다.

양자 리소스의 수직 확장을 칩의 더 많은 Qubit으로, 수평 확장을 커플러로 여러 칩을 연결하는 것으로 보여주는 이미지.

이해도 점검

고전 (a) 정보 비트, (b) 프로세서 속도에 해당하는 양자 유사물은 무엇인가요?

정답:

(a) 양자 비트 또는 Qubit - 고전적인 대응물(0 또는 1의 상태만 가질 수 있음)과 달리 0과 1의 중첩 상태에 동시에 있을 수 있는 정보 단위입니다.

(b) 초당 Circuit 레이어 연산 수 또는 CLOPS - QPU가 초당 수행할 수 있는 순차 연산의 수로, Circuit에서 파라미터를 로드하는 것과 같이 고전 컴퓨팅 리소스와의 일부 인터페이싱도 포함합니다.

리소스 관리

HPC 리소스와 양자 리소스는 모두 귀중하고 복잡하므로 신중하게 관리해야 합니다. 이 섹션에서는 사용자 프로그램을 위한 리소스 관리 방법을 설명합니다. 컴퓨팅 인프라에서의 리소스 관리란 CPU, 메모리, 스토리지, 네트워크 대역폭 등 컴퓨팅 리소스의 사용을 (1) 계획하고, (2) 할당하고, (3) 제어/관리하여 효율적이고 효과적인 리소스 활용을 보장하는 과정을 말합니다.

계획 - 리소스 추정

모든 프로그램은 리소스를 소비하며, 효율적인 리소스 관리를 위해 필요한 리소스를 추정하는 것이 매우 중요합니다. 여기에는 프로그램 실행에 필요한 CPU, 메모리 및 기타 리소스의 양을 추정하는 과정이 포함됩니다. 양자 리소스도 마찬가지입니다. 다만 양자 리소스는 완전히 다른 규모로 존재합니다. IBM Quantum® Heron r3 양자 프로세서는 156개의 Qubit을 갖추고 있는데, 이는 일반 노트북에 탑재된 수십억 개의 고전 비트와 비교됩니다. 시간과 비용도 고려 사항입니다. 현재 IBM Quantum은 월 10분의 QPU 시간을 제공하는 무료 플랜인 Open Plan을 통해 사용자들이 양자 컴퓨팅을 탐색할 수 있도록 하고 있습니다. 일부 연구 기관은 QPU 시간이 매우 많이 필요하여 전용 IBM 양자 컴퓨터를 구내에 설치하기도 합니다.

리소스 추정에서 양자 컴퓨팅에만 고유한 단계 중 하나는 Circuit 깊이입니다. 앞서 언급한 것처럼, 각 양자 Gate와 연산 사이의 각 지연 시간에는 노이즈와 일정 확률의 오류가 수반됩니다. 양자 Circuit이 깊어질수록 노이즈도 커집니다. 여기에는 두 가지 미묘한 점이 있습니다. 2-Qubit Gate는 1-Qubit Gate보다 오류율이 훨씬 높으므로 1-Qubit 깊이는 종종 무시할 수 있습니다. 또한 양자 칩의 모든 Qubit이 직접 연결되어 있지는 않습니다. 필요한 얽힘을 수행하기 위해 Qubit에서 Qubit으로 정보를 교환해야 할 때도 있으며, 이 교환 과정 자체에 2-Qubit Gate가 필요합니다. 그 교환은 '트랜스파일레이션(transpilation)'이라는 과정에서 처리되는데, 이는 다른 목적도 수행하는 복잡한 과정으로 다음 레슨에서 더 자세히 다룹니다. 따라서 관련 제한 수량은 트랜스파일된 2-Qubit 깊이입니다. 고충실도 결과를 얻을 수 있는 정확한 최대 깊이는 Circuit에 따라 다릅니다. 하지만 현대적인 오류 완화 기법을 활용하면 트랜스파일된 2-Qubit 깊이가 80 이상이더라도 고충실도 결과를 얻을 수 있습니다.

할당 - 스케줄링

스케줄링은 프로그램에 리소스를 할당하고 실행을 관리하는 과정입니다. 여기에는 다음이 포함됩니다.

  • 작업 제출: 사용자가 HPC 시스템에 실행에 필요한 컴퓨팅 작업과 리소스를 지정하는 요청(작업)을 보내는 과정입니다.
  • 리소스 할당: 제출된 작업의 요구 사항에 따라 노드, CPU, 메모리 등 사용 가능한 HPC 시스템 리소스를 해당 작업에 배정하는 것입니다.
  • 작업 실행: 할당된 HPC 리소스에서 작업에 정의된 컴퓨팅 태스크를 실제로 실행하는 것입니다.

양자 컴퓨터에도 이러한 모든 과정에 대응하는 것들이 있습니다.

  • 작업은 Qiskit Runtime을 활용하여 사용자가 제출하며, 일반적으로 Sampler, Estimator 등과 같은 Qiskit Runtime Primitive를 사용합니다.
  • 사용자는 접근 권한이 있는 Backend 목록에서 선택합니다. 사용 가능한 Backend의 전체 목록은 IBM Quantum Platform의 Compute resources 페이지에서 확인할 수 있습니다. 일반적으로는 가장 덜 바쁜 양자 컴퓨터를 사용하지만, 장치 레이아웃 고려 사항이나 이전 계산의 재현 등의 이유로 특정 양자 컴퓨터를 사용해야 하는 경우도 있습니다.
  • 양자 작업의 실행은 HPC의 경우와 유사합니다. 이미 몇 가지 차이점이 설명되었지만, 반복할 가치가 있는 것들이 있습니다. QPU는 현재 일반적으로 고전 컴퓨팅 리소스와 같은 노드에 위치하지 않으며 네트워크를 통해 연결됩니다. 이는 스케줄링에 영향을 미칠 수 있습니다. 또한 양자 컴퓨터는 상당한 대기 시간이 발생할 수 있으며, 이 대기 시간은 변동이 있어 타이밍을 정확하게 제어하기 어렵습니다. 이 상황은 전용 시스템의 경우 다를 수 있으며, 이는 해당 양자 컴퓨터의 내부 관리 방식에 따라 달라집니다.

제어/관리 - 워크로드 관리

워크로드 관리(오케스트레이션이라고도 함)는 여러 프로그램과 그 리소스 요구 사항을 관리하는 과정입니다. 여기에는 다음이 포함됩니다.

  • 리소스 프로비저닝: 하드웨어 및 소프트웨어 설정을 포함하여 HPC 리소스를 작업에서 사용할 수 있도록 준비하고 제공하는 과정입니다. 뒤에서 살펴보겠지만, QPU는 이전 섹션의 주의 사항을 감안하여 고전 HPC 리소스와 유사한 방식으로 프로비저닝할 수 있는 컴퓨팅 리소스입니다.
  • 작업 스케줄링: 스케줄러 소프트웨어가 어떤 작업을, 언제, 어떤 리소스에서 실행할지 결정하고 우선순위와 큐를 관리하여 HPC 시스템을 효율적으로 활용하는 활동입니다. 이 광범위한 설명은 양자 리소스에도 적용되지만, 다른 리소스에 비해 타이밍 제어가 덜 가능할 수 있습니다.

워크로드(박스로 표시)가 한 축은 시간, 다른 축은 리소스를 나타내는 2차원 그리드에 최적으로 배치되고 정렬되는 모습을 보여주는 이미지. 예시:

리소스 관리를 이해하기 위한 맥락으로 잘 알려진 태스크를 고려해 보겠습니다: 큰 수의 소인수 분해입니다. 사용되는 알고리즘이 모든 잠재적 약수를 일일이 검사하는 무차별 대입 방식에 의존한다고 가정해 봅시다. 이 방법이 항상 가장 효율적인 것은 아니지만, 워크로드 관리 방식을 이해하기 쉽습니다.

계획 - 리소스 추정

  • 소인수 분해에 필요한 CPU 시간과 메모리를 추정합니다.
  • 태스크의 병렬화를 계획합니다 - 몇 개의 CPU/코어를 사용할 것인지 결정합니다.

할당 - 스케줄링

  • 작업 제출 시, 스케줄러가 소인수 분해 태스크에 CPU 코어와 메모리를 배정합니다. 예를 들어, 끝자리가 1, 3, 7, 9인 모든 잠재적 약수를 각각 네 개의 코어 중 하나에 배정할 수 있습니다.
  • 작업 실행: 소인수 분해 알고리즘이 실행되어 태스크가 완료될 때까지 할당된 리소스에서 나눗셈이나 다른 인수 분해 단계를 수행합니다.

제어/관리 - 워크로드 관리

  • 시스템이 처리량을 최적화하기 위해 소인수 분해 작업의 순서와 타이밍을 조율합니다.
  • 가장 쉽게 상상할 수 있는 경우는 코어 중 하나가 목표 소인수를 찾는 것입니다. 이렇게 되면 다른 코어의 계산을 중단하여 다음 태스크에 사용할 수 있게 해야 합니다.

고성능 컴퓨팅 환경은 이러한 단계를 수행하고 리소스를 관리하기 위한 특수 소프트웨어를 사용합니다. 다음 섹션에서는 널리 채택된 리소스 관리 소프트웨어 시스템인 Slurm에 대해 알아보겠습니다.

양자 리소스를 이용한 예시:

이 과정의 다른 레슨에서 다룰 워크플로는 샘플 기반 양자 대각화(SQD, Sample-Based Quantum Diagonalization)를 사용하여 화학적 바닥 상태와 에너지를 결정하는 것입니다. 이는 레슨 4에서 더 자세히 다루며, SQD에 관한 이 과정IBM Quantum Learning의 관련 방법도 참고할 수 있습니다. 이 논의를 위해 알아야 할 것은 워크플로에 다음이 포함된다는 것입니다.

  • 양자 Circuit 준비
  • 양자 Circuit 측정
  • 측정 결과를 이용하여 문제를 유용한 부분 공간으로 투영
  • 고전 컴퓨팅 리소스를 이용하여 더 작은 투영 행렬 대각화
  • 전하 보존과 같은 고려 사항을 통한 자기 일관성 확보와 Circuit에 변분 매개변수가 있는 경우의 반복 등 반복 수행.

계획 - 리소스 추정

  • 전자 오비탈을 Qubit에 매핑하여 필요한 Qubit 수를 결정합니다.
  • 시스템의 매핑된 해밀토니안과 (변분이 있을 수 있는) 상태를 양자 Circuit으로 결합하고 트랜스파일된 2-Qubit 깊이를 확인합니다. 적절한지 확인합니다.
  • 투영할 부분 공간의 크기를 추정하고, 이를 통해 대각화에 필요한 CPU 시간과 메모리를 추정합니다.
  • 태스크의 병렬화를 계획합니다 - 몇 개의 CPU/코어를 사용할 것인지 결정합니다.

할당 - 스케줄링

  • 사용자가 QPU를 선택하면, 트랜스파일레이션 과정이 추상 양자 Circuit의 Qubit을 QPU의 물리적 Qubit에 자동으로 매핑합니다. 이는 추상 Circuit이 칩에 존재하지 않는 직접 연결성을 가정할 수 있는 등 여러 이유로 중요합니다.
  • Qiskit Runtime을 통해 작업을 제출하면 선택한 QPU의 큐에 들어갑니다. 사용자는 큐 대기 시간을 제어할 수 없지만, 전용 시스템의 경우는 다를 수 있습니다.
  • 고전 컴퓨팅 리소스는 양자 결과를 기다립니다.
  • HPC 리소스에 대각화 작업이 제출되고, 작업 제출 시 스케줄러가 대각화 태스크에 CPU 코어와 메모리를 배정합니다.
  • 작업 실행: 대각화 알고리즘이 실행되어 태스크가 완료될 때까지 더 작은 투영 행렬을 대각화합니다.

제어/관리 - 워크로드 관리

  • 시스템이 전체 과정에 걸쳐 양자 및 고전 단계의 순서와 타이밍을 조율합니다. 예를 들어, 투영 행렬이 대각화되고 바닥 상태 에너지가 얻어지면, 수렴 기준에 따라 워크플로는 (새로운 변분 매개변수를 가진) 새 양자 Circuit으로 되돌아갈 수 있습니다.
  • 바닥 상태 에너지가 수렴 기준을 충족하면 모든 코어의 계산이 중단됩니다.

고성능 컴퓨팅 환경은 이러한 단계를 수행하고 리소스를 관리하기 위한 특수 소프트웨어를 사용합니다. 다음 섹션에서는 널리 채택된 리소스 관리 소프트웨어 시스템인 Slurm에 대해 알아보겠습니다. 중요한 점은 Slurm이 위에서 설명한 모든 단계를 위한 도구를 제공하지는 않는다는 것입니다. Slurm은 작업 계획이나 워크로드 구성 요소 간의 통신 같은 세부적인 워크로드 관리를 지원하지 않습니다. 이는 QPU가 일반적으로 네트워크를 통해 접근되는 HPC 내 양자 컴퓨팅의 현재 상태에 잘 맞습니다.

이해도 확인

정렬되지 않은 데이터베이스에서 '목표'라고 부를 원소를 찾는다고 가정해 봅시다. 다음 각 행동에 대해 리소스 관리의 어느 단계에 해당하는지 말해 보세요. (a) 데이터베이스의 크기와 각 원소를 확인하는 데 필요한 시간 추정하기 (b) 하나의 GPU에서 목표를 찾았을 때 다른 GPU의 프로세스를 중단하여 다음 문제를 위해 해방시키기 (c) 검색 공간을 10개의 GPU가 각각 검색할 영역으로 분할하기

Answer:

(a) 계획 (b) 제어/관리 (c) 할당/스케줄링,

소프트웨어: Slurm

이 섹션에서는 이 장에서 배운 개념을 적용하여 널리 사용되는 자원 관리 시스템인 Slurm을 실습합니다.

Slurm 소개

Slurm은 고성능 컴퓨팅 환경에서 널리 사용되는 오픈 소스 자원 관리 시스템입니다. 자원 관리, 작업 스케줄링, 시스템 성능 모니터링을 위한 포괄적인 도구 모음을 제공합니다.

Slurm의 기본 사용법을 다음 항목을 중심으로 살펴보겠습니다.

  • 작업 제출
  • 자원 할당
  • 작업 모니터링

이 강좌의 모든 수강생에게 HPC 자원을 실제로 제공하기가 매우 어렵기 때문에, Docker 이미지가 담긴 저장소를 제공하여 소규모이지만 실제 Slurm HPC 클러스터를 모사하는 환경을 구성했습니다. 이를 통해 안전하고 재현 가능한 환경에서 배운 개념을 실습할 수 있습니다.

현재 모든 양자 및 클래식 자원은 실험 전체 기간 동안 할당된다는 점에 유의하세요. 현재는 혼합 자원의 인터리브 할당을 지원하지 않습니다. 마지막으로, 작업이 실행되더라도 양자 시스템은 일반적인 HPC 사용자가 기대하는 방식으로 직접 제어되지 않습니다. 작업은 임의의 x86 노드에서 실행되며, 해당 노드가 Qiskit Runtime 서비스를 실행하고 그 서비스가 사용자가 직접 제어할 수 없는 다른 스케줄러에 연결됩니다. 이 워크플로와 관련 이슈는 GPU 노드 독점 접근을 초기에 시도했던 HPC 사용자에게 익숙할 수 있습니다(원래의 gres 사용 사례).

설치 안내 및 설정 개요

양자 자원과 HPC 자원을 결합하는 실습을 하려면 실제 HPC 환경에 접근하거나 로컬 머신에서 HPC 환경을 시뮬레이션해야 합니다. Docker를 사용한 로컬 설정 안내는 이 저장소에서 확인할 수 있습니다. 해당 안내서에는 IBM Cloud® 계정 설정 및 QRMI용 SPANK 플러그인 설치에 대한 링크도 포함되어 있습니다. 또한 해당 저장소에는 환경을 테스트하기 위한 여러 Python 파일이 있습니다.

설치를 완료했다면, 아래 명령어를 사용하여 터미널에서 Slurm의 컴퓨팅 자원을 확인해 보세요. 설치가 성공했다면 총 세 개의 가상 노드를 확인할 수 있어야 합니다.

$ sinfo

PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
normal up 5-00:00:00 2 idle c[1-2]
quantum* up infinite 1 idle q1
$ scontrol show node

NodeNAME=q1 Arch=x86_64 CoresPerSocket=1
CPUAlloc=0 CPUTot=1 CPULoad=0.34
AvailableFeatures=(null)
ActiveFeatures=(null)
Gres=qpu:1
NodeAddr=q1 NodeHostName=q1 Version=21.08.6
...

파티션(노드 그룹)이 두 개 있습니다: normal과 quantum. normal 파티션은 클래식 자원만 접근 가능한 노드로 구성됩니다. quantum 파티션은 양자 자원에 접근할 수 있습니다. scontrol show nodes를 실행하면 각 노드의 세부 정보를 확인할 수 있습니다.

Slurm에서 간단한 hello world 예제 실행하기

먼저 Slurm으로 간단한 클래식 hello world 예제를 실행해 보겠습니다. 예제에는 Python을 사용합니다. 내용이 자명한 hello_world.py를 생성해 보겠습니다.

$ vim hello_world.py

import time
time.sleep(10)
print("Hello, World!")
~

이제 자원 관리자에게 이 프로그램을 실행하는 데 필요한 자원을 알려줘야 합니다. Slurm은 제출 스크립트를 통해 작업에 필요한 모든 메타데이터를 지정하는 방법을 제공합니다. 제출 스크립트는 Slurm 전용 어노테이션이 포함된 셸 스크립트입니다. 이 어노테이션을 통해 자원 요구 사항, 스케줄 매개변수 등을 지정할 수 있습니다. 이를 위해 hello_world.sh 셸 스크립트를 생성해 보겠습니다.

$ vim hello_world.sh

#SBATCH --job-name=hello-world
#SBATCH --output=hello-world.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=normal

srun hello_world.py
~

제출 파일을 살펴보며 무슨 일이 일어나고 있는지 확인해 보겠습니다.

#SBATCH 지시문은 프로그램 실행에 필요한 요구 사항을 지정하는 어노테이션입니다. 노드 수, 노드당 태스크 수, 노드 및 태스크당 태스크와 CPU 수 등의 자원 양과 출력 파일 이름 같은 기타 옵션을 지정할 수 있습니다. 전체 옵션 목록은 Slurm 공식 문서에서 확인할 수 있습니다.

이제 Slurm 작업을 실행할 차례입니다. sbatch는 제출 파일을 받아 Slurm의 실행 큐에 작업을 등록하는 명령어입니다.

$ sbatch hello_world.sh

Submitted batch job 63

squeue 명령어를 사용하여 프로그램 상태를 확인해 보겠습니다.

$ squeue

# JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
# 1 main hello_world root R 0:01 1 c1

작업이 완료되면 출력 파일을 확인하여 결과를 볼 수 있습니다.

$ cat hello_world_logs.txt
Hello, World!

이해도 확인

아래의 Slurm 셸 스크립트를 보고 (a) 작업 이름, (b) Python 파일 이름, (c) 출력 파일 이름은 무엇인가요? (d) 마지막으로, 이 스크립트가 양자 자원을 사용할 수 있나요?

vim hello_learner.sh

#SBATCH --job-name=hello-learner
#SBATCH --output=hello-learner.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum

srun hello_learner_qm.py

정답:

(a) hello-learner (b) hello-learner_qm.py (c) hello-learner.out (d) 네, 가능합니다. quantum 파티션을 사용하고 있기 때문입니다.

Slurm에서 간단한 Qiskit hello world 예제 실행하기

다음으로 양자 자원도 함께 사용해 보겠습니다. 양자 자원을 사용하는 간단한 "Hello, Qiskit" 프로그램을 만들고 실행해 보겠습니다.

$ vim hello_qiskit.py

# hello_qiskit.py
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import EstimatorV2 as Estimator

# Create a new circuit with two qubits
qc = QuantumCircuit(2)

# Add a Hadamard gate to qubit 0
qc.h(0)

# Perform a controlled-X gate on qubit 1, controlled by qubit 0
qc.cx(0, 1)

observables_labels = ["IZ", "IX", "ZI", "XI", "ZZ", "XX"]
observables = [SparsePauliOp(label) for label in observables_labels]

# switch to QRMI service
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

backend = service.backend("...")

# Convert to an ISA circuit and layout-mapped observables.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)

# Construct the Estimator instance.

estimator = Estimator(mode=backend)
estimator.options.resilience_level = 1
estimator.options.default_shots = 5000

mapped_observables = [
observable.apply_layout(isa_circuit.layout) for observable in observables
]

# One pub, with one circuit to run against five different observables.
job = estimator.run([(isa_circuit, mapped_observables)])

job_result = job.result()

pub_result = job.result()[0]

print("Result", pub_result)

여기서는 양자 자원 관리 인터페이스(QRMI)를 사용합니다. QRMI는 IBM, Pasqal, The Hartree Centre, RPI가 공동으로 개발한 양자 자원 및 작업 지원을 위한 Slurm SPANK 플러그인입니다. 무작위 초기값을 가진 간단한 pauli-2-design Circuit과 단순한 observable을 만들었으며, Estimator를 사용하여 기댓값을 구해 보겠습니다. 실행을 위해 양자 자원을 요구 사항으로 포함한 제출 스크립트 hello_qiskit.sh가 다시 필요합니다.

$ vim hello_qiskit.sh

#SBATCH --job-name=hello-qiskit
#SBATCH --output=hello_qiskit.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-nodes=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum
#SBATCH --gres=qpu:1

srun python /data/ch2/hello_qiskit/hello_qiskit.py
~

제출 파일을 살펴보며 어떤 일이 일어나는지 확인해 보겠습니다. 새로운 옵션으로 gres가 추가되었습니다. gres는 추가 컴퓨팅 자원을 정의하는 Slurm 옵션입니다. 이 경우 새로운 자원은 양자 자원이 됩니다. 자원과 양자 자원이 사용 가능한 클러스터 파티션을 지정했으므로, Qiskit Primitives는 할당된 자원을 사용하여 양자 페이로드를 실행합니다.

이제 Slurm 작업을 실행할 차례입니다.

$ sbatch hello_qiskit.sh

그런 다음, squeue 명령어를 사용하여 프로그램 상태를 확인해 보겠습니다.

$ squeue
# JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
# 1 main hello_qiskit root R 0:01 1 q1

작업이 완료된 후 로그와 결과를 확인할 수 있습니다.

$ cat hello_qiskit.out | grep Exp
Expectation Value: 0.8372900070983516

요약

지금까지 컴퓨팅 자원이 무엇인지, 그리고 이를 이종 환경에서 프로그램을 실행하는 데 어떻게 활용하는지 배웠습니다. 또한 클래식 자원용과 양자 자원용 두 가지 간단한 'Hello World' 프로그램을 만들고 실행했으며, 작업을 제출하고 결과를 확인하기 위한 셸 스크립트를 작성하는 방법도 익혔습니다.

다음 강의에서는 이 자원 제어에 대한 지식을 바탕으로, 작업 실행 중 확보한 자원에 프로그래밍 모델을 적용하는 방법을 알아보겠습니다.

이 장에서 사용된 모든 코드와 스크립트는 GitHub 저장소에서 확인할 수 있습니다.