콘텐츠로 이동

문제해결

코어 덤프 파일 생성

PyTorch RBLN 실행 중 문제가 발생한 경우, 생성된 코어 덤프 파일을 client_support@rebellions.ai로 전달해 주시기 바랍니다. 코어 덤프 파일을 생성하려면 우선 아래 명령어로 ulimit 제한을 해제해야 합니다.

$ ulimit -c unlimited

ulimit 제한이 정상적으로 해제되었는지 확인하려면 다음 명령어를 실행합니다.

$ ulimit -c
unlimited

이후 문제가 발생한 모델 스트립트를 실행하면 에러가 발생하면서 /var/crash 경로에 코어 덤프 파일이 생성됩니다.

1
2
3
$ ls /var/crash
-rw-r----- 1 rebel1    root   779026 Jul  2 17:50 /var/crash/_usr_bin_python3.10.2029.crash
-rw-r----- 1 rebel2    root 94849351 Jun 25 18:27 /var/crash/_usr_bin_python3.10.2035.crash

CPU에서 실행되는 연산자 로깅

PyTorch RBLN에서 아직 지원하지 않는 PyTorch 연산자나 특정 데이터 타입이 사용될 경우, 프로그램의 중단 없는 실행을 위해 해당 연산은 CPU에서 대신 수행됩니다. 이 기능은 모델의 호환성을 높여주지만, 해당 연산은 NPU의 성능 이점을 활용하지 못하므로 최적화 과정에서 어떤 연산이 CPU에서 실행되는지 파악하는 것이 중요합니다.

기본적으로 PyTorch RBLN의 로그 레벨은 WARNING 으로 설정되어 있어, 디버깅(DEBUG) 메시지는 출력되지 않습니다. 따라서 NPU 성능 최적화를 위해 CPU에서 실행되는 모든 연산자를 확인하려면, 아래와 같이 환경 변수를 DEBUG 로 명시적으로 설정해야 합니다.

사용법:

$ export TORCH_RBLN_LOG=DEBUG

다시 default 값으로 설정하려면 아래와 같이 환경변수를 설정합니다.

$ export TORCH_RBLN_LOG=WARNING

출력 예시:

이 설정을 적용하고 Eager Mode로 모델을 실행하면, Rebellions NPU가 아닌 CPU에서 연산이 수행될 때마다 아래와 같이 해당 연산자의 이름과 (trace가 가능한 경우) 소스 코드 위치가 로그로 출력됩니다.

1
2
3
[TORCH-RBLN][DEBUG] 'aten::pow' ran on CPU instead of RBLN
/transformers/models/llama/modeling_llama.py:73: UserWarning: TRACE
  variance = hidden_states.pow(2).mean(-1, keepdim=True)

torch.Tensor.to 이후에 결과가 틀리는 경우

증상

  • RBLN에서 CPU로 텐서를 이동한 후 CPU 기준값 대비 불일치가 발생하거나 그 후속 CPU 코드에서 FP16 관련 이상 동작이 발생하는 경우입니다.

영향

  • 수치적인 오차나 잠재적인 정확도 문제가 발생합니다.

원인

  • RBLN은 커스텀 16비트 부동 소수점 형식으로 16비트 부동 소수점 연산을 합니다. 텐서는 torch.float16 형식으로 보여질 수 있지만 명시적인 변환을 거치지 않으면 커스텀 부동 소수점 형식을 그대로 유지합니다. to("cpu")만을 사용하면 이 속성이 그대로 CPU로 옮겨집니다.

해결 방법

tensor = tensor.to("cpu", dtype=torch.float16)

검증 예제 (최소 비교)

import torch

def elements_sum(n, device):
    x = torch.ones(n, dtype=torch.float16, device=device)
    y = torch.full_like(x, 0.5, dtype=torch.float16, device=device)
    return x + y

out = elements_sum(2, "rbln")
baseline = elements_sum(2, "cpu")

implicit_move = out.to("cpu")
explicit_cast = out.to("cpu", dtype=torch.float16)

print("baseline     :", baseline.tolist())
print("implicit_move:", implicit_move.tolist())
print("explicit_cast:", explicit_cast.tolist())

예제 결과

1
2
3
baseline     : [1.5, 1.5]
implicit_move: [1.75, 1.75]
explicit_cast: [1.5, 1.5]

비고

  • 디바이스에서도 필요한 경우 torch.to(dtype=torch.float16)로 캐스팅해서 쓸 수 있습니다.
  • CPU로 텐서를 옮길 때, CPU에서 비교를 하거나 연산을 수행하기 전에 to("cpu", dtype=torch.float16)을 사용하는 것이 좋습니다.

메모리 통계가 예상보다 낮게 표시되는 경우

증상

  • 메모리 통계 API (예: memory_allocated(), memory_stats())가 RBLN 디바이스에 텐서를 생성한 직후 예상보다 낮은 값을 반환
  • 큰 텐서를 할당한 후에도 디바이스 메모리 사용량이 0이거나 매우 낮게 표시됨

영향

  • 실제 메모리 사용량에 대한 혼란
  • 모델 실행 중 메모리 소비 모니터링의 어려움

원인

  • RBLN 텐서는 lazy memory allocation을 사용합니다. RBLN 디바이스에 텐서를 생성할 때:
    • 텐서는 생성 시점에 CPU 메모리에 즉시 할당됩니다
    • 디바이스 메모리 할당은 실제로 디바이스 연산이 필요할 때까지 지연됩니다
    • 디바이스 연산이 필요할 때 텐서 데이터가 CPU에서 디바이스 메모리로 lazy하게 전송됩니다
  • 모든 메모리 관련 API (예: memory_allocated(), memory_reserved(), memory_stats())는 디바이스 메모리만 반영하며, CPU 메모리는 포함하지 않습니다
  • 추가로, Dynamo caching (torch.compile()에서 사용)이 컴파일된 그래프와 관련 디바이스 메모리를 캐시할 수 있어 디바이스 메모리 사용에 영향을 줄 수 있습니다. 텐서만의 정확한 메모리 통계를 보려면 통계 확인 전에 Dynamo 캐시를 리셋하세요

해결 방법

  • 텐서가 디바이스에서 materialize되는 연산을 수행한 후에 메모리 통계를 확인하세요
  • 텐서가 실제로 디바이스 연산에 사용될 때 메모리 통계가 증가합니다

예제

import torch
import torch.rbln

# 텐서 생성
x = torch.randn(1024, 1024, device="rbln")
y = torch.randn(1024, 1024, device="rbln")

# 생성 직후 메모리 통계는 낮을 수 있음
print("생성 후:", torch.rbln.memory_allocated() / 1024, "KB")

# 디바이스 연산 수행하여 텐서 materialize
z = x + y

# Dynamo 캐시 리셋하여 캐시된 그래프 메모리를 통계에서 제외
torch._dynamo.reset()

# materialize 후 메모리 통계는 실제 디바이스 메모리 사용량을 반영
print("연산 후:", torch.rbln.memory_allocated() / 1024, "KB")

비고

  • 이것은 예상된 동작이며 버그가 아닙니다. Lazy allocation 전략은 필요할 때까지 디바이스 메모리 할당을 지연시켜 메모리 사용을 최적화합니다
  • 정확한 디바이스 메모리 사용량을 확인하려면 텐서가 디바이스에서 materialize되는 연산을 수행한 후 통계를 확인하세요
  • CPU 메모리는 즉시 할당되지만, 디바이스 메모리 통계는 materialization 후에만 반영됩니다
  • Dynamo caching이 컴파일된 그래프를 디바이스 메모리에 보관할 수 있습니다. 캐시된 그래프 메모리를 제외하고 텐서 메모리 사용량만 확인하려면 메모리 통계 확인 전에 torch._dynamo.reset()을 사용하세요