PyTorch 2.14에서 CUDA Graph Trees 세대 전환 시 사용자 출력 유지하기 | DAKER 커뮤니티

그래프트리 복제

긴 디코드나 스트리밍 추론처럼 CUDA Graph Trees를 여러 세대에 걸쳐 쓰는 경로에서는, 이전 스텝의 출력 텐서를 계속 참조하는 코드가 예상과 다르게 동작할 수 있습니다. 특히 세대가 바뀌는 순간, 사용자 쪽에서 붙잡고 있던 출력이 끊기는지 여부는 성능만큼이나 안정성에 영향을 줍니다.

PyTorch 2.14에서는 이 지점을 확인해 볼 수 있는 선택 설정이 있습니다. torch._inductor.config.triton.cudagraph_trees_generation_cloning = "user_visible"을 켜면, 사용자에게 보이는 출력을 세대 전환 이후에도 복제해 유지합니다. 오늘 바로 비교해 볼 수 있는 실험 포인트이기도 합니다.

Inductor CUDA Graph Trees에서 세대가 바뀌면, 이전 세대에 살아 있던 사용자 출력 텐서가 끊길 수 있습니다.
PyTorch 2.14의 선택 설정 torch._inductor.config.triton.cudagraph_trees_generation_cloning = "user_visible"을 켜면 사용자에게 보이는 출력을 세대 넘김에도 복제·유지합니다.

무엇이 달라지는가

핵심은 그래프 트리의 세대 전환과 사용자 출력의 수명입니다. 기본 설정에서는 이전 세대의 출력 참조가 다음 세대로 넘어가면서 그대로 유지되지 않을 수 있습니다. 반면 cudagraph_trees_generation_cloning="user_visible"을 켜면, 사용자에게 노출되는 출력은 복제되어 세대가 바뀐 뒤에도 살아 있도록 동작합니다.

이 차이는 특히 이전 스텝의 출력 텐서를 다음 스텝 입력이나 로깅에 다시 쓰는 코드에서 드러납니다. 짧은 실행에서는 잘 보이지 않을 수 있지만, 여러 스텝을 이어 가는 경로에서는 바로 확인할 수 있습니다.

재현해 볼 실험 조건

비교는 같은 시퀀스를 기본값과 user_visible 설정으로 각각 실행해 보면 됩니다. 모델은 짧게 컴파일되는 쪽이 확인에 유리하고, reduce-overhead 또는 CUDA Graph Trees가 켜지는 모드에서 올리면 됩니다.

  1. CUDA Graph Trees가 동작하는 설정으로 작은 모델을 컴파일하고, 세대를 넘기는 입력 시퀀스를 준비합니다.
  2. 기본 설정으로 N스텝을 돌리며, 이전 스텝 출력 텐서를 다음 스텝 입력·로깅에 다시 참조합니다.
  3. 같은 시퀀스에 cudagraph_trees_generation_cloning="user_visible"을 켠 뒤, 출력 유효성·복사 비용·스텝 시간을 비교합니다.

여기서 보는 축은 CUDA 그래프 while_loop 캡처나 지역성 재배치와는 다릅니다. 이번에는 그래프 트리의 세대와 사용자 출력 수명만 분리해서 보는 것이 좋습니다.

실무에서 먼저 볼 지점

스트리밍 추론에서 과거 출력 버퍼를 붙잡아 두는 코드가 있다면, 세대 전환 직후 참조가 깨지는지부터 확인해 두는 편이 좋습니다. 반대로 출력을 바로 소비하고 버리는 경로라면, 복제 비용이 추가되는 user_visible보다 기본값이 더 잘 맞을 수 있습니다.

비교 결과를 남길 때는 Inductor 설정 키와 CUDA 드라이버·빌드 번호를 함께 적어 두면 재현성이 좋아집니다. 같은 코드라도 환경 차이에 따라 체감이 달라질 수 있기 때문입니다.

복제는 안전 비용을 치르므로, 출력을 바로 소비하고 버리는 경로에는 기본값이 더 맞을 수 있습니다.

관련 자료

PyTorch 실전 고급 트랙
DAKER 커뮤니티

여러분 환경에서는 세대 전환 뒤 출력 참조 안정성과 스텝 시간 사이의 균형이 어떻게 보였는지 궁금합니다.