AKS(Azure Kubernetes Service) GPU 프로파일링 불꽃 그래프 분석(미리 보기)

GPU 프로파일링 불꽃 그래프는 GPU 메모리를 가장 많이 사용하는 함수를 보여 줍니다. 이 문서에서는 AKS(Azure Kubernetes Service) GPU 프로파일링 도구에서 생성된 불꽃 그래프를 해석하는 방법을 설명합니다.

Important

AKS 미리 보기 기능은 셀프 서비스에서 사용할 수 있습니다(옵트인 방식). 미리 보기는 "있는 그대로" 및 "사용 가능한 상태로" 제공되며 서비스 수준 계약 및 제한적 보증에서 제외됩니다. AKS 미리 보기의 일부는 고객 지원팀에서 최선을 다해 지원합니다. 따라서 이러한 기능은 프로덕션 용도로 사용할 수 없습니다. 자세한 내용은 다음 지원 문서를 참조하세요.

시작하기 전에 GPU 프로파일링을 설정하고 프로파일링 데이터를 파이로스코프 및 Grafana에서 사용할 수 있는지 확인합니다.

메모

프로파일러가 워크로드를 분석하고 기호를 확인하는 동안 첫 번째 프로파일링 실행은 모델 로드와 같은 시작 작업의 기호를 포함하여 모든 기호를 표시하지 않을 수 있습니다. 초기 분석 후 워크로드를 다시 실행하여 후속 프로필에서 이러한 기호를 캡처합니다.

화염 그래프 이해

화염 그래프는 프로파일된 호출 스택을 시각화합니다. 각 막대는 함수를 나타내고 누적 막대는 호출 체인 또는 다른 함수라고 하는 함수를 표시합니다. 각 막대의 너비는 해당 함수를 통해 흐르는 CPU 시간 또는 할당된 GPU 메모리와 같은 측정된 리소스의 양을 나타냅니다.

키 규칙: 막대가 넓을수록 측정된 리소스가 해당 함수를 통해 더 많이 흐릅니다.

다음 샘플 화염 그래프는 vLLM 유추 워크로드에서 캡처됩니다.

GPU 메모리 할당 호출 스택을 나타내는 누적 막대를 보여 주는 vLLM 워크로드에 대한 Grafana의 초기 축소된 불꽃 그래프 보기 스크린샷

Tip

Grafana의 플레임 그래프 패널에서 모든 그룹 펼치기를 사용하면 전체 호출 스택을 접지 않고 볼 수 있습니다. 검색 상자를 사용하여 특정 함수 또는 키워드를 찾습니다. 패널이 다시 축소되지 않도록 하려면 확장된 불꽃 그래프를 검사하는 동안 Grafana 대시보드의 오른쪽 위 모서리에서 새로 고침 간격을 Off 로 설정하여 대시보드 자동 새로 고침을 일시 중지합니다.

“Expand all groups”를 선택한 후 Grafana에서 vLLM 워크로드의 불꽃 그래프를 캡처한 스크린샷으로, GPU 메모리 할당을 위한 개별 함수 프레임이 포함된 전체 호출 스택을 보여 줍니다.

Tip

포커스 블록을 사용하여 특정 할당 경로에 집중합니다.

기호 읽기

화염 그래프 레이블은 다음 규칙을 따릅니다.

기호 형식 Meaning
Foo > bar class Foo: method def bar()
Foo > __init__ 클래스 생성자 Foo
bar (단독으로) 독립 실행형 def bar() 함수
<interpreter trampoline> CPython 오버헤드. 이 기호는 무시할 수 있습니다.
<raw-address>, 예를 들어, 0x7f151 사용할 수 있는 Python 기호가 없는 네이티브 C 또는 CUDA 코드입니다.

예는 다음과 같습니다.

  • GPUModelRunner / _allocate_kv_cache_tensors: 클래스의 메서드입니다. 이 기호는 class GPUModelRunner: def _allocate_kv_cache_tensors(self)로 읽습니다.
  • LlamaMLP / __init__: 개체를 만들 때 호출되는 생성자입니다 LlamaMLP(...) .
  • _compile_fx_inner: 클래스 내에 없는 독립 실행형 모듈 수준 함수입니다.

자체 할당과 총 할당 비교 이해하기

Self 및 Total 값을 사용하여 리소스가 사용되는 위치를 결정합니다.

  • Total 은 함수에서 사용하는 리소스와 호출하는 모든 리소스입니다. 함수는 총합이 클 수 있지만 호출 체인의 일부이기 때문에 아무 것도 할당하지 않습니다.
  • 자체 함수는 자식 함수를 제외하고 함수에서 직접 사용하는 리소스입니다. 높은 자체 값은 이 함수가 리소스를 사용하는 위치임을 의미합니다.

예를 들어 GPUModelRunner._allocate_kv_cache_tensors의 자체 할당이 55.1GB라면, 키-값(KV) 캐시 텐서를 만들기 위해 torch.empty()를 호출하는 함수입니다.

다음 탐색 기술을 사용합니다.

  • 리프 노드로 시작합니다. 이 노드는 그 위에 아무 것도 없는 막대입니다. 전체 너비는 자체 할당을 나타냅니다.
  • 할당의 원인을 찾을 때 자체 할당량이 0인 너비가 넓은 막대는 건너뜁니다. 이러한 함수는 다른 함수에 대한 호출을 오케스트레이션합니다.
  • 잠재적인 최적화 대상으로 삼을 수 있는, 자체 할당이 높은 넓은 막대를 조사하세요.

가장 큰 리소스 소비자 찾기

다음 단계를 사용하여 핫스팟을 식별합니다.

  1. 그래프 위쪽에서 가장 넓은 막대를 확인합니다. 이러한 리프 함수는 메모리를 할당합니다. 막대가 넓을수록 더 많은 메모리를 사용합니다.

  2. 자체 할당과 총 할당을 확인합니다. 아래쪽 self: 0 의 넓은 막대가 호출 체인의 일부입니다. 자체 할당량이 높은 막대를 찾을 때까지 위로 따라 올라가세요.

  3. 함수가 호출된 이유를 이해하려면 맨 아래에서 위쪽으로 호출 스택을 읽어보세요. 다음 예제는 할당을 수행하는 함수로 끝납니다.

    <raw-address>, for example, 0x7f151       -> native code entry
    <interpreter trampoline>                 -> CPython dispatch
    <module>                                 -> script top level
    EngineCoreProc.run_engine_core           -> vLLM engine startup
    EngineCore.__init__                      -> engine initialization
    EngineCore._initialize_kv_caches         -> KV cache setup
    Worker.initialize_from_config            -> worker setup
    GPUModelRunner.initialize_kv_cache       -> model runner
    GPUModelRunner._allocate_kv_cache_tensors -> actual allocation
    

빠른 참조로 다음 표를 사용합니다.

목표 확인할 사항
가장 많은 메모리를 할당하는 항목을 찾습니다. 스택 맨 위에 있는 가장 넓은 리프 막대
메모리를 가장 많이 차지하는 항목 찾기 스택 맨 아래에 있는 가장 넓은 막대
최적화 대상 식별 자동 할당 폭이 넓은 막대
건너뛸 수 있는 함수 식별 자체 할당이 0인 폭이 넓은 막대

다음 단계