Accelerate documentation

Profiler

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v1.15.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Profiler

Profiler는 학습 및 추론 중에 성능 메트릭을 수집할 수 있는 도구입니다. Profiler의 컨텍스트 매니저 API를 사용하면 가장 비용이 높은 모델 연산자를 파악하고, 해당 연산자의 입력 형식과 스택 트레이스를 검토하며, 디바이스 커널 활동을 분석하고, 실행 트레이스를 시각화할 수 있습니다. 이는 모델의 성능에 대한 통찰력을 제공하여 최적화 및 개선이 가능하도록 합니다.

이 가이드에서는 PyTorch Profiler를 사용하여 모델의 연산자 시간 및 메모리 사용량을 측정하는 방법과 이를 Accelerate에 통합하는 방법을 설명합니다. 다양한 사용 사례를 다루고 각 사례에 대한 예제를 제공합니다.

프로파일러를 사용하여 실행 시간 분석

Profiler를 사용하면 프로파일러 컨텍스트 매니저로 감싸진 코드 구간의 실행 중에 어떤 연산자가 호출되었는지 확인할 수 있습니다.

profiler를 사용하여 실행 시간을 분석하는 방법을 살펴보겠습니다:

PyTorch
Accelerate
import torch
import torchvision.models as models
from torch.profiler import profile, record_function, ProfilerActivity

model = models.resnet18()
inputs = torch.randn(5, 3, 224, 224)

with profile(activities=[ProfilerActivity.CPU], record_shapes=True) as prof:
    model(inputs)

print(prof.key_averages().table(sort_by="cpu_time_total", row_limit=10))

생성된 테이블 출력(일부 열 생략):

---------------------------------  ------------  ------------  ------------  ------------  
                             Name      Self CPU     CPU total  CPU time avg    # of Calls  
---------------------------------  ------------  ------------  ------------  ------------  
                     aten::conv2d     171.000us      52.260ms       2.613ms            20  
                aten::convolution     227.000us      52.089ms       2.604ms            20  
               aten::_convolution     270.000us      51.862ms       2.593ms            20  
         aten::mkldnn_convolution      51.273ms      51.592ms       2.580ms            20  
                 aten::batch_norm     118.000us       7.059ms     352.950us            20  
     aten::_batch_norm_impl_index     315.000us       6.941ms     347.050us            20  
          aten::native_batch_norm       6.305ms       6.599ms     329.950us            20  
                 aten::max_pool2d      40.000us       4.008ms       4.008ms             1  
    aten::max_pool2d_with_indices       3.968ms       3.968ms       3.968ms             1  
                       aten::add_     780.000us     780.000us      27.857us            28  
---------------------------------  ------------  ------------  ------------  ------------  
Self CPU time total: 67.016ms

더 세밀한 결과의 세분화 수준을 얻고 연산자 입력 형상을 포함하려면 group_by_input_shape=True를 전달하세요(참고: 이 옵션은 프로파일러를 record_shapes=True로 실행해야 합니다):

print(prof.key_averages(group_by_input_shape=True).table(sort_by="cpu_time_total", row_limit=10))

프로파일러를 사용하여 메모리 사용량 분석

Profiler는 모델의 연산자 실행 중에 할당(또는 해제)된 메모리 양(모델의 텐서가 사용하는 메모리)도 표시할 수 있습니다. 메모리 프로파일링 기능을 활성화하려면 profile_memory=True를 전달하세요.

PyTorch
Accelerate
model = models.resnet18()
inputs = torch.randn(5, 3, 224, 224)

with profile(activities=[ProfilerActivity.CPU],
        profile_memory=True, record_shapes=True) as prof:
    model(inputs)

print(prof.key_averages().table(sort_by="self_cpu_memory_usage", row_limit=10))

생성된 테이블 출력(일부 열 생략):

---------------------------------  ------------  ------------  ------------  
                             Name       CPU Mem  Self CPU Mem    # of Calls  
---------------------------------  ------------  ------------  ------------  
                      aten::empty      94.85 Mb      94.85 Mb           205  
    aten::max_pool2d_with_indices      11.48 Mb      11.48 Mb             1  
                      aten::addmm      19.53 Kb      19.53 Kb             1  
                       aten::mean      10.00 Kb      10.00 Kb             1  
              aten::empty_strided         492 b         492 b             5  
                        aten::cat         240 b         240 b             6  
                        aten::abs         480 b         240 b             4  
              aten::masked_select         120 b         112 b             1  
                         aten::ne          61 b          53 b             3  
                         aten::eq          30 b          30 b             1  
---------------------------------  ------------  ------------  ------------  
Self CPU time total: 69.332ms

전체 연산자 테이블 대신 실험 추적에 필요한 집계 숫자 1~2개만 필요하시다면, PyTorch가 노출하는 런타임 메모리 통계와 프로파일러를 조합하세요. 이는 실행당 피크 메모리 사용량을 기록하는 데 일반적으로 충분합니다:

import torch
from accelerate import Accelerator, PartialState, ProfileKwargs

# Resolve the device type/module (cuda, xpu, ...) instead of hardcoding CUDA
device_type = PartialState().device.type
device_module = getattr(torch, device_type)


def summarize_memory_stats():
    return {
        "peak_allocated_mb": device_module.max_memory_allocated() / 1024**2,
        "peak_reserved_mb": device_module.max_memory_reserved() / 1024**2,
    }


profile_kwargs = ProfileKwargs(
    activities=["cpu", device_type],
    profile_memory=True,
    record_shapes=True,
)

accelerator = Accelerator(kwargs_handlers=[profile_kwargs])

device_module.reset_peak_memory_stats()

with accelerator.profile() as prof:
    model(inputs)

print(prof.key_averages().table(sort_by=f"self_{device_type}_memory_usage", row_limit=10))
print(summarize_memory_stats())

이 패턴은 프로파일러 출력을 디버깅용으로 유지하면서 실험 트래커에 기록할 수 있는 간결한 값을 생성합니다.

Chrome trace 내보내기

Chrome trace viewer(chrome://tracing)에서 프로파일링된 연산자와 CUDA 커널의 순서를 확인할 수 있습니다:

profile_export

PyTorch
Accelerate
# Pick the available accelerator (cuda, xpu, ...) instead of hardcoding CUDA
device = torch.accelerator.current_accelerator()
device_activity = getattr(ProfilerActivity, device.type.upper())

model = models.resnet18().to(device)
inputs = torch.randn(5, 3, 224, 224).to(device)

with profile(activities=[ProfilerActivity.CPU, device_activity]) as prof:
    model(inputs)

prof.export_chrome_trace("trace.json")

Profiler를 사용하여 장기 실행 작업 분석

Profiler는 장시간 실행되는 작업(예: 학습 루프)을 처리하기 위한 추가 API를 제공합니다. 모든 실행을 추적하면 느려질 수 있으며 매우 큰 trace 파일이 생성될 수 있습니다. 이를 피하려면 선택적 인수를 사용하세요:

  • schedule_option: 스케줄링 옵션을 사용하면 프로파일링이 활성화되는 시점을 제어할 수 있습니다. 이는 데이터 수집량이 과도해지지 않도록 장시간 실행되는 작업에서 유용합니다. 사용 가능한 키는 wait, warmup, active, repeat, skip_first입니다. 프로파일러는 처음 skip_first 스텝을 건너뛰고, wait 스텝을 기다린 후, 다음 warmup 스텝 동안 워밍업을 수행하고, 다음 active 스텝 동안 활성 기록을 수행한 후, wait 스텝으로 시작하여 사이클을 반복합니다. 선택적인 사이클 횟수는 repeat 파라미터로 지정하며, 0 값은 프로파일링이 완료될 때까지 사이클이 계속됨을 의미합니다.
  • on_trace_ready: 프로파일러의 참조를 입력으로 받는 함수를 지정하며, 프로파일러가 새로운 trace가 준비될 때마다 이 함수를 호출합니다.

API가 어떻게 작동하는지 설명하기 위해 다음 예시를 살펴보세요:

PyTorch
Accelerate
from torch.profiler import schedule

my_schedule = schedule(
    skip_first=1,
    wait=5,
    warmup=1,
    active=3,
    repeat=2
)

def trace_handler(p):
    output = p.key_averages().table(sort_by=f"self_{device.type}_time_total", row_limit=10)
    print(output)
    p.export_chrome_trace("/tmp/trace_" + str(p.step_num) + ".json")

with profile(
    activities=[ProfilerActivity.CPU, device_activity],
    schedule=my_schedule,
    on_trace_ready=trace_handler
) as p:
    for idx in range(8):
        model(inputs)
        p.step()

FLOPS

formula를 사용하여 특정 연산자(행렬 곱셈 및 2D 컨볼루션)의 FLOPs(부동소수점 연산)를 추정합니다.

부동소수점 연산(FLOPS)을 측정하려면:

PyTorch
Accelerate
with profile(
    activities=[ProfilerActivity.CPU, device_activity],
    with_flops=True
) as prof:
    model(inputs)

print(prof.key_averages().table(sort_by="flops", row_limit=10))

생성된 테이블 출력(일부 열 생략):

-------------------------------------------------------  ------------  ------------  ------------  
                                                   Name      Self CPU     Self CUDA    Total FLOPs  
-------------------------------------------------------  ------------  ------------  ------------  
                                           aten::conv2d     197.000us       0.000us  18135613440.000  
                                            aten::addmm     103.000us      17.000us     5120000.000  
                                              aten::mul      29.000us       2.000us          30.000  
                                      aten::convolution     409.000us       0.000us            --  
                                     aten::_convolution     253.000us       0.000us            --  
                                aten::cudnn_convolution       5.465ms       2.970ms            --  
                                        cudaEventRecord     138.000us       0.000us            --  
                                  cudaStreamIsCapturing      43.000us       0.000us            --  
                                  cudaStreamGetPriority      40.000us       0.000us            --  
                       cudaDeviceGetStreamPriorityRange      10.000us       0.000us            --  
-------------------------------------------------------  ------------  ------------  ------------  
Self CPU time total: 21.938ms
Self CUDA time total: 4.165ms

결론 및 추가 정보

PyTorch Profiler은 모델의 성능을 분석하는 강력한 도구입니다. Accelerate와 통합하면 모델을 쉽게 프로파일링하여 성능에 대한 통찰력을 얻을 수 있으며, 이를 통해 모델을 최적화하고 개선하는 데 도움이 됩니다.

자세한 정보는 PyTorch Profiler 문서를 참조하세요.

Update on GitHub