트레이스를 열기 전에 질문을 선택하세요
트레이스는 특정 질문에 더 잘 답합니다: 연산이 데이터를 기다리고 있는지, 복사가 반복되는지, 아니면 작은 연산자가 너무 자주 호출되는지 말이죠. 입력, 출력, 단계의 경계를 정의하세요. 학습의 경우 백워드, 옵티마이저 업데이트, 배치 읽기가 포함되는지 명시하세요. 추론의 경우 모델 로딩과 요청을 분리하세요.
정답을 알고 있는 짧은 시나리오를 유지하세요. 형태, 배치, 정밀도, 모델 모드, 가능한 컴파일, 데이터 출처를 기록하세요. 단순화된 입력은 동작을 분리하는 데 도움이 될 수 있지만, 더 이상 전체 부하를 대표하지 않을 수 있습니다. 이 차이를 기록에 명시하세요.
최종 단위를 정하세요: 단계당 밀리초 또는 초당 처리 예시 수. 이벤트 합계는 경과 시간을 대체하지 않습니다. 동일한 읽기 및 전송 경계를 가진 윈도우를 비교하세요.
CPU 시간, GPU 작업, 대기 시간 구분하기
CPU는 연산을 준비하고 실행을 시작하며, GPU는 이를 나중에 실행할 수 있습니다. 따라서 Python의 한 구간에는 실행 시작, 대기 또는 둘 다가 포함될 수 있습니다. PyTorch의 CUDA 문서에 따르면 정확한 측정은 이러한 비동기성을 고려해야 하며, 특히 범위에 맞는 동기화나 이벤트를 사용해야 합니다.
GPU 지속 시간을 특정 대상으로 측정할 때는 CUDA 이벤트가 적합할 수 있습니다. 종단 간 지연 시간을 측정할 때는 해당 지연 시간에 포함된 작업이 끝날 때까지 기다린 뒤 요청 전체를 측정하세요. 이 두 단위를 섞지 마세요. 각 연산 사이에 동기화를 추가하면 실제 겹침이 사라져, 이해하려는 프로그램 자체가 달라질 수 있습니다.
프로파일러에서도 연산자의 자체 시간과 하위 연산을 포함한 시간은 서로 다른 질문에 답합니다. 표의 행을 더하기 전에 타임라인을 먼저 보세요. 동시에 또는 중첩되어 실행되는 활동은 서로 겹치지 않는 경과 시간의 일부가 아닙니다.
시작 단계와 활성 구간을 구분하기
첫 번째 실행에는 초기화, 로딩 또는 컴파일이 포함될 수 있습니다. 질문이 이 시작 단계에 관한 것인지, 이미 안정된 단계에 관한 것인지 결정하세요. 전체 평균인 것처럼 제시된 값에서 초기 비용을 지워버리지 말고, 사용에 중요하다면 두 관측값을 모두 유지하세요.
schedule 함수를 사용하면 대기, 수집 준비, 활성 구간을 구분할 수 있습니다. 프로파일러의 워밍업은 모델이 안정 상태에 도달했다는 증거가 아닙니다. 마주치는 형상과 캐시 상태도 확인하세요. 입력이 가변적인 애플리케이션은 여러 반복 이후에 새로운 경로를 만날 수 있습니다.
아래에 제시된 학습 계획은 한 단계를 기다리고, 한 단계를 준비하며, 두 단계를 캡처합니다. 메커니즘을 설명하기에는 네 단계로 충분하지만, 성능 분포를 확립하기에는 부족합니다. 실제 캠페인에서는 정당화된 윈도를 선택하고 분석 후 프로파일러 없이 측정을 반복하세요.
제안 예시: 경계가 명확한 네 단계
다음 코드 조각은 실행되지 않았습니다. model, optimizer, loss_fn, loader, device가 존재하고, 모델이 device 위에 있으며, 로더가 최소 네 개의 x, y 쌍 배치를 제공한다고 가정합니다. 이 조각은 가중치를 갱신합니다. 따라서 가중치를 보존해야 하는 세션이 아니라, 이를 위해 마련된 실험용 상태를 사용하세요.
레이블은 CPU 읽기, 전송, 학습을 구분합니다. 이터레이터는 측정 구간 전에 생성되므로, 시작 단계의 일부는 측정 범위에서 제외됩니다. 기존 트레이스를 덮어쓰지 않도록 파일은 새 이름으로 선택합니다. 이 예제는 GPU 수집이 불가능할 때 이를 숨기고 CPU 트레이스를 GPU 분석인 것처럼 제시하는 대신 오류를 냅니다.
step() 신호는 매 단계 후에 스케줄을 진행시킵니다. 공식 레시피도 반복과 수집 사이의 이 연결을 설명합니다. ROCm 스택에서는 PyTorch 장치 이름이 여전히 cuda이지만, 가속기 수집 가능 여부는 빌드와 해당 도구에 따라 달라집니다. 결과에 실제로 어떤 활동이 포함되어 있는지 확인하세요.
from pathlib import Path
import torch
from torch.profiler import (
profile, schedule, record_function,
ProfilerActivity, supported_activities,
)
trace = Path("trace-etape.json")
if trace.exists():
raise FileExistsError("새 트레이스 이름을 선택하세요")
activities = [ProfilerActivity.CPU]
if device.type == "cuda":
if ProfilerActivity.CUDA not in supported_activities():
raise RuntimeError("이 빌드에서는 GPU 수집을 사용할 수 없습니다")
activities.append(ProfilerActivity.CUDA)
iterator = iter(loader)
model.train()
with profile(
activities=activities,
schedule=schedule(wait=1, warmup=1, active=2, repeat=1),
record_shapes=False, profile_memory=False, with_stack=False,
on_trace_ready=lambda p: p.export_chrome_trace(str(trace)),
) as prof:
for _ in range(4):
with record_function("lecture_batch_cpu"):
x, y = next(iterator)
with record_function("transfert"):
x, y = x.to(device), y.to(device)
with record_function("entrainement"):
optimizer.zero_grad(set_to_none=True)
loss = loss_fn(model(x), y)
loss.backward()
optimizer.step()
prof.step()
print(prof.key_averages().table(
sort_by="self_cpu_time_total", row_limit=8,
))관찰을 검증 가능한 가설로 바꾸기
먼저 활성 구간부터 보고 예상한 레이블이 나타나는지 확인하세요. 그다음 활동 사이의 공백, 복사, 반복을 살펴보세요. lecture_batch_cpu에서의 긴 대기는 입력 파이프라인을 가리키지만, 저장소를 직접 측정하는 것은 아닙니다. 잦은 복사는 텐서 배치를 점검해 보라는 신호일 뿐, 그것이 불필요하다는 증거는 아닙니다.
가설을 하나만 세우고 통제된 변경을 제안하세요. 예를 들어 어떤 상수가 매 단계마다 다시 생성되어 전송된다면, 결과를 바꾸지 않으면서 그 수명을 여러 단계에 걸쳐 유지할 수 있는지 확인하세요. 어떤 연산자가 지배적으로 보인다면, 대체 연산자를 찾기 전에 그 형태와 호출 횟수를 먼저 살펴보세요.
아래 행들은 가능한 해석이며, 실행된 트레이스에서 도출한 사실이 아닙니다. 어떤 소요 시간이나 가속도 단정하지 않습니다. 유용한 결론은 제시된 원인을 확인하거나 반박할 수 있는 다음 실험입니다.
표의 모든 열을 보려면 스크롤하세요.| 가능한 관찰 | 가설 | 다음 점검 |
|---|---|---|
| 읽기 동안 GPU 활동 없음 | 입력 파이프라인이 따라가지 못함 | 이미 준비된 배치로 같은 계산 수행 |
| 상수가 반복적으로 복사됨 | 배치 또는 수명이 부적절함 | 한 번만 이동하고 출력 확인 |
| 잦은 소규모 실행 | 작업이 조각화됨 | 묶음 처리와 전체 비용 검토 |
| 하나의 긴 연산자 | 결정적인 형태 또는 알고리즘 | 같은 연산자와 입력 비교 |
계측의 비용과 정보량 줄이기
짧고 옵션이 적은 수집으로 시작하세요. 형태, 스택, 메모리는 질문이 요구할 때만 활성화하세요. PyTorch API에 따르면 이러한 정보는 추가 비용을 발생시키며, 형태 수집은 텐서에 대한 참조를 유지할 수도 있습니다. 따라서 상세 프로파일링은 프로그램의 소요 시간이나 메모리 사용량을 바꿀 수 있습니다.
트레이스에는 연산자 이름, 셰이프, 그리고 옵션에 따라 코드 경로가 포함될 수 있습니다. 공유하기 전에 반드시 검사하세요. 영역 레이블은 이메일, 토큰, 비공개 경로, 입력 내용을 포함하지 않고 단계를 설명해야 합니다. 환경에 맞는 트레이스 뷰어를 선택하고 수집을 직접 통제하세요.
예상했던 GPU 이벤트가 없다면 그 시간을 0으로 채우지 마세요. 관측되지 않았다고 명시하고 수집 지원을 점검하세요. 도구에서 이벤트가 없다는 것이 계산이 없었다는 증거는 아닙니다.
프로파일러 없이 최적화 검증하기
동일한 관련 상태에서 시작하여 수정 전후의 정확성을 비교하세요. 학습의 경우 추가 단계가 가중치를 바꾸므로 연속으로 실행한 두 캡처가 반드시 동등한 비교가 되지는 않습니다. 코드, 매개변수, 시작 지점을 보존하여 차이를 설명할 수 있게 하세요.
그다음 세부 수집 없이 동일한 워밍업과 여러 번의 실행으로 시나리오를 측정하세요. 범위, 원시 값, 분산을 보고하세요. 국소적 개선이 전체 루프에서 사라지거나 품질을 저하시킬 수 있으므로 둘 다 결정에 포함되어야 합니다.
마지막으로 관측값을 사용하여 실제로 필요한 리소스를 구체화하세요. 로컬 머신의 트레이스는 Kernodeck 요금제를 분류하지 않으며 임대 서버의 호스트 CPU나 네트워크를 증명하지도 않습니다. GPU 비교에는 관련 리소스에 대한 동등한 워크로드, 조건, 결과가 필요합니다.