RBLN PyTorch API 및 지원 연산¶
이 페이지는 RBLN PyTorch의 레퍼런스 문서입니다. rbln 백엔드의 디바이스 모듈로 등록되는 torch.rbln과 RBLN NPU에서 실행하는 PyTorch 연산자를 정리합니다. 대부분의 PyTorch 코드는 RBLN 전용 함수를 호출할 필요가 없습니다. torch.rbln API는 디바이스 선택, 동기화, 스트림, 메모리, 진단에 사용하며 대응 API가 있는 경우 torch.cuda와 같은 방식으로 사용합니다.
torch.rbln 모듈¶
import torch를 실행하면 torch.rbln이 자동으로 등록됩니다. 다음 표는 모든 공개 심볼을 그룹별로 나누고 대응하는 torch.cuda API가 있으면 함께 표시합니다. 각 표 뒤에는 소스 docstring에서 생성한 상세 시그니처가 이어집니다.
디바이스 관리¶
| API | torch.cuda 대응 API | 요약 |
|---|---|---|
torch.rbln.is_available() | is_available | RBLN을 가속기로 사용할 수 있는지 반환합니다. 예외를 발생시키지 않으며 런타임이 없거나 디바이스가 보이지 않거나 RBLN_* 디바이스 설정이 잘못되면 False를 반환합니다. |
torch.rbln.device_count() | device_count | 논리 RBLN 디바이스 수입니다. 예외를 발생시키지 않으며 앞과 같은 경우 0을 반환합니다. 설정이 잘못되면 경고를 표시합니다. |
torch.rbln.physical_device_count() | — | RSD 그룹 설정과 관계없이 프로세스에 보이는 물리 NPU 수입니다. 디바이스를 점유하거나 매핑을 확정하지 않습니다. |
torch.rbln.current_device() | current_device | 현재 선택한 논리 디바이스의 인덱스입니다. |
torch.rbln.set_device(device) | set_device | 현재 디바이스를 선택합니다. 관리 상태만 변경하며 NPU를 점유하지 않습니다. torch.rbln.device 컨텍스트 관리자를 권장합니다. |
torch.rbln.device(device) | device | 선택한 디바이스를 변경하고 종료 시 이전 디바이스로 복원하는 컨텍스트 관리자입니다. |
torch.rbln.device_of(obj) | device_of | 주어진 텐서의 디바이스를 선택하는 컨텍스트 관리자입니다. |
torch.rbln.synchronize(device=None) | synchronize | 디바이스에서 대기 중인 비동기 전송이 끝난 뒤 해당 디바이스의 모든 스트림이 완료될 때까지 기다립니다. |
torch.rbln.is_initialized() | is_initialized | 디바이스를 선택했거나 디바이스가 없으면 True를 반환합니다. |
torch.rbln.is_dummy_device() | — | NPU가 아닌 호스트 기반 더미 디바이스에서 실행 중이면 True를 반환합니다. |
torch.rbln.device_summary() | — | 논리 디바이스와 물리 NPU의 매핑 표, 사용하지 않는 NPU가 있으면 경고를 출력합니다. |
torch.rbln.get_device_properties(device=None) | get_device_properties | 논리 디바이스에 속한 NPU의 속성입니다. name, total_memory(논리 디바이스에 속한 NPU의 메모리 합계), npu_count, NPU별 num_chiplet과 memory_per_chiplet을 표시합니다. 메모리를 할당하거나 디바이스를 점유하지 않습니다. 더미 디바이스에서는 예외가 발생합니다. |
torch.rbln.get_device_name(device=None) | get_device_name | 논리 디바이스에 속한 NPU의 이름입니다. 예: "RBLN-CA25". |
torch.rbln.get_amp_supported_dtype() | get_amp_supported_dtype | RBLN에서 자동 혼합 정밀도를 지원하는 dtype입니다. 이번 릴리스에는 autocast dtype이 등록되지 않아 빈 목록을 반환합니다. |
Rebellions Scalable Design(RSD)으로 여러 ATOM™ NPU를 하나의 rbln:N으로 묶으면 논리 디바이스와 물리 NPU가 달라집니다. Rebel100™ 카드는 칩렛 네 개로 구성된 고정 RSD-4 그룹이며 항상 1:1로 매핑됩니다. device_count()는 논리 디바이스 수를, physical_device_count()는 보이는 물리 NPU 수를 반환합니다. 그룹 설정에 사용하는 RBLN_DEVICE_MAP과 RBLN_NPUS_PER_DEVICE는 환경 변수에서 설명합니다. 같은 이유로 get_device_properties()의 total_memory는 논리 디바이스에 속한 NPU의 메모리를 합산하고 memory_per_chiplet은 칩렛별 값을 표시합니다. 메모리 사용량이 가장 큰 칩렛에서 메모리가 부족해지므로 메모리 풀 크기는 memory_per_chiplet을 기준으로 결정해야 합니다.
device(device) ¶
Context-manager that changes the selected device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | torch.device, int, str, or None | device index to select. It is a no-op if this argument is a negative integer or | required |
device_of(obj) ¶
Context-manager that changes the current device to that of given object.
You can use both tensors and storages as arguments. If a given object is not allocated on an RBLN device, this is a no-op.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj | Tensor or Storage | object allocated on the selected device. | required |
Example
is_available() ¶
Check if any RBLN devices are available.
Returns:
| Name | Type | Description |
|---|---|---|
bool | bool | True if at least one RBLN device is available, False otherwise. |
device_count() ¶
Get the number of available RBLN devices.
Returns:
| Name | Type | Description |
|---|---|---|
int | int | The number of available RBLN devices. |
physical_device_count() ¶
Get the number of physical RBLN devices in the system.
This function returns the actual number of physical devices, regardless of whether logical device aggregation is enabled.
Returns:
| Name | Type | Description |
|---|---|---|
int | int | The number of physical RBLN devices. |
current_device() ¶
Get the index of the currently selected RBLN device.
Returns:
| Name | Type | Description |
|---|---|---|
int | int | The index of the currently selected RBLN device. |
set_device(device) ¶
Set the current device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | device or int or str | selected device. | required |
synchronize(device=None) ¶
Wait for all work on the given RBLN device: its pending asynchronous transfers, then every stream on it (torch.cuda.synchronize parity).
If no device is specified, the current device is used.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | device or int or str | The device to synchronize. Defaults to the current device. | None |
is_initialized() ¶
True once set_device() has run, or when there are no devices at all.
The no-device case is deliberate: it makes torch.distributed's init_device_mesh skip its get_rank() % device_count() auto-select, which would otherwise fail on a host with no NPU.
Note: this calls device_count(), which plans the RBLN device mapping from the current RBLN_* environment. It does not claim an NPU or freeze the mapping; both happen on first device use, so a launcher may still assign RBLN_DEVICES afterwards.
is_dummy_device() ¶
Whether the process runs on a host-backed dummy device rather than an NPU.
is_available() is True on a dummy device too, so use this to tell a dummy device apart from real NPU availability.
Returns:
| Name | Type | Description |
|---|---|---|
bool | bool | True on a dummy device, False otherwise. |
device_summary() ¶
Print a summary of the RBLN device topology showing the mapping between logical devices and physical NPU IDs.
The table shows:
- Logical device indices (
rbln:0,rbln:1, ...) - Physical NPU IDs mapped to each logical device
- Status of each device (
Active,Active (Aggregated), orUnused) - A warning about unused physical devices, if any
The device mapping is determined by the following environment variables (in order of priority):
RBLN_DEVICE_MAP: explicit groups, for example"[0,1],[2,3,4,5]"RBLN_NPUS_PER_DEVICE: uniform groups of the given size, for example"2"
Example
get_device_properties(device=None) ¶
Describe the NPUs behind an RBLN logical device (torch.cuda parity).
A logical device may span several physical NPUs (RBLN_DEVICE_MAP / RBLN_NPUS_PER_DEVICE), so total_memory sums them and npu_count says how many. num_chiplet and memory_per_chiplet stay per NPU: a device runs out on its heaviest chiplet, which total_memory hides, so size a pool by memory_per_chiplet.
The query does not allocate memory or claim the device, so it is safe to call before the runtime initializes. Properties are not cached: each call queries every NPU behind the logical device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | device or int or str | The device to query. Defaults to the current device. | None |
Returns:
| Name | Type | Description |
|---|---|---|
DeviceProperties | DeviceProperties | An object with the read-only attributes |
Raises:
| Type | Description |
|---|---|
RuntimeError | on a dummy device (host-backed, no NPU to report on), when no NPU is mapped to the index, when the runtime cannot answer for one of them, or when the NPUs of the logical device differ in name or chiplet count. |
get_device_name(device=None) ¶
Return the NPU name behind an RBLN logical device, for example "RBLN-CA25" (torch.cuda parity).
Same as get_device_properties(device).name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | device or int or str | The device to query. Defaults to the current device. | None |
Returns:
| Name | Type | Description |
|---|---|---|
str | str | The NPU name. |
get_amp_supported_dtype() ¶
Get a list of data types supported by automatic mixed precision (AMP) on RBLN devices.
Returns:
| Type | Description |
|---|---|
List[dtype] | List[torch.dtype]: A list of data types supported by AMP. |
Note
Automatic mixed precision is not implemented for RBLN devices yet, so this currently returns an empty list. As a result, entering torch.autocast("rbln") emits a warning and leaves autocast disabled instead of raising an error.
난수 생성¶
이 함수들은 가속기의 RNG 상태를 저장하고 복원하는 torch.random.fork_rng 같은 PyTorch 유틸리티가 rbln에서 동작하도록 합니다. 각 rbln 디바이스에는 고유한 상태를 가진 기본 generator가 있습니다. 이번 릴리스에서 rbln의 난수 생성 연산자는 여전히 CPU에 고정되어 있습니다. generator 인자 없이 호출하면 PyTorch의 기본 CPU generator가 아니라 대상 rbln 디바이스의 기본 generator를 사용합니다. 이 함수들이 저장하고 복원하는 상태는 CPU에 고정된 난수 연산자에만 영향을 줍니다. 아직 디바이스 커널 내부의 난수 상태에는 영향을 주지 않으므로 이 상태를 설정해도 vLLM의 무작위 샘플링처럼 디바이스에서 생성한 결과의 재현성을 보장하지 않습니다.
| API | torch.cuda 대응 API | 요약 |
|---|---|---|
torch.rbln.get_rng_state(device="rbln") | get_rng_state | 디바이스의 RNG 상태를 ByteTensor로 반환합니다. 인덱스 없는 "rbln"은 현재 디바이스를 뜻합니다. |
torch.rbln.get_rng_state_all() | get_rng_state_all | 모든 논리 디바이스의 RNG 상태를 디바이스 인덱스 순서로 반환합니다. |
torch.rbln.set_rng_state(new_state, device="rbln") | set_rng_state | get_rng_state()에서 받은 상태로 해당 디바이스의 RNG 상태를 복원합니다. |
torch.rbln.set_rng_state_all(new_states) | set_rng_state_all | get_rng_state_all()에서 받은 순서에 따라 모든 디바이스의 RNG 상태를 복원합니다. |
get_rng_state(device='rbln') ¶
Return the random number generator state of device as a ByteTensor (torch.cuda.get_rng_state parity).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | device or int or str | The device to query. Defaults to | 'rbln' |
Returns:
| Type | Description |
|---|---|
Tensor | torch.Tensor: The generator state. |
get_rng_state_all() ¶
Return the random number generator state of every device, in device-index order.
Returns:
| Type | Description |
|---|---|
List[Tensor] | List[torch.Tensor]: One state per logical device. |
set_rng_state(new_state, device='rbln') ¶
Set the random number generator state of device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
new_state | Tensor | A state produced by | required |
device | device or int or str | The device to set. Defaults to | 'rbln' |
set_rng_state_all(new_states) ¶
Set the random number generator state of every device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
new_states | Iterable[Tensor] | States ordered like the result of | required |
스트림과 이벤트¶
스트림과 이벤트는 torch.cuda.Stream, torch.cuda.Event와 같은 방식으로 사용합니다. 범용 클래스인 torch.Stream, torch.Event에서도 device="rbln"로 접근할 수 있습니다.
| API | torch.cuda 대응 API | 요약 |
|---|---|---|
torch.rbln.Stream(device=None, priority=0) | Stream | 디바이스 작업을 순서대로 실행하는 스트림입니다. 스트림 간 순서는 이벤트로 제어합니다. 이번 릴리스에서는 스트림을 나누어도 디바이스 측 병렬성이 추가되지 않습니다(실행 방식 › 스트림 참고). priority는 API 정합성을 위해 받지만 무시합니다. 스트림은 디바이스별 고정 풀에서 가져오며 풀 크기를 초과하면 이전 스트림을 재사용합니다. |
torch.rbln.Event(enable_timing=False, blocking=False, interprocess=False) | Event | 스트림에 기록하여 스트림 간 순서를 제어하고 완료 여부를 조회하는 마커입니다. 세 플래그는 받지만 무시하며 elapsed_time()은 지원하지 않습니다. 프로세스 간 공유도 지원하지 않습니다. ipc_handle()과 from_ipc_handle()은 NotImplementedError를 발생시킵니다. |
torch.rbln.current_stream(device=None) | current_stream | 디바이스에서 현재 선택한 스트림입니다. |
torch.rbln.default_stream(device=None) | default_stream | 디바이스의 기본 스트림입니다. |
torch.rbln.stream(stream) | stream | stream을 현재 스트림으로 선택하고 종료 시 이전 스트림으로 복원하는 컨텍스트 관리자입니다. None이면 아무 작업도 하지 않습니다. |
torch.rbln.set_stream(stream) | set_stream | 현재 스트림을 설정합니다. stream 컨텍스트 관리자를 권장합니다. |
torch.rbln.StreamContext | StreamContext | stream()에서 사용하는 컨텍스트 관리자 클래스입니다. |
Stream(device=None, priority=0) ¶
An in-order sequence of device work on an RBLN NPU.
Work submitted to the same stream runs in order, while work on different streams may run concurrently. Use a stream to overlap a copy with compute, and an Event to order work between two streams.
Streams come from a fixed per-device pool. Once the pool is exhausted, new instances reuse earlier streams.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | torch.device, int, str, or None | The device the stream belongs to. If None, uses the current device. Defaults to None. | None |
priority | int | Accepted for API parity and ignored, because RBLN NPUs have no stream priorities. Defaults to 0. | 0 |
query() ¶
Check whether all work submitted to this stream has completed.
Returns:
| Name | Type | Description |
|---|---|---|
bool | bool | True if the stream has no pending work. |
synchronize() ¶
Block the calling host thread until all work submitted to this stream completes.
Waits on this stream only. A pending asynchronous transfer is tracked per device, not per stream, so use torch.rbln.synchronize() to wait for those.
wait_event(event) ¶
Make all future work submitted to this stream wait for event.
A device-side fence when event was recorded on this stream's device: the call returns without blocking the host. RBLN has no cross-device fence, so an event recorded on another device is waited on the host instead. Ordering holds either way; what changes is that the caller is serialized.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event | Event | The event to wait for. | required |
wait_stream(stream) ¶
Make all future work submitted to this stream wait for the work already submitted to stream.
Records an event on stream and waits for it, so the cross-device rule in wait_event() applies here too.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stream | Stream | The stream to synchronize with. | required |
Event(enable_timing=False, blocking=False, interprocess=False) ¶
A marker recorded in a stream, used to order work across streams and to query completion.
RBLN NPUs do not support event timing: elapsed_time() raises a RuntimeError, and the constructor flags are accepted for API parity but ignored. Waiting on an event recorded on another device falls back to a host-side synchronize.
Cross-process event sharing is not supported: ipc_handle() and from_ipc_handle() are inherited from torch.Event and raise NotImplementedError: torch.Event ipc is not supported yet, so interprocess=True grants no capability. Both attributes are present, so a capability probe that only looks them up succeeds and the failure surfaces at the call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enable_timing | bool | Accepted for API parity and ignored. Defaults to False. | False |
blocking | bool | Accepted for API parity and ignored. Defaults to False. | False |
interprocess | bool | Accepted for API parity and ignored; RBLN events cannot be shared across processes. Defaults to False. | False |
Example
record(stream=None) ¶
Record the event in a stream.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stream | Stream | The stream to record in. If None, uses the current stream. Defaults to None. | None |
wait(stream=None) ¶
Make all future work submitted to a stream wait for this event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stream | Stream | The stream that waits. If None, uses the current stream. Defaults to None. | None |
query() ¶
Check whether the work captured by this event has completed.
Returns:
| Name | Type | Description |
|---|---|---|
bool | bool | True if every work item recorded before the event has completed. |
synchronize() ¶
Block the calling host thread until the work captured by this event completes.
StreamContext(stream) ¶
Context-manager that selects a given stream, restoring the previously selected one on exit.
The stream's device is selected for the duration. Create one with stream().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stream | Stream or None | The stream to select. It is a no-op if None. | required |
current_stream(device=None) ¶
Return the currently selected stream for a given device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | int, str, or torch.device | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Name | Type | Description |
|---|---|---|
Stream | Stream | The currently selected stream. |
default_stream(device=None) ¶
Return the default stream for a given device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | int, str, or torch.device | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Name | Type | Description |
|---|---|---|
Stream | Stream | The default stream. |
stream(stream) ¶
Return a context manager that selects the given stream.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stream | Stream or None | The stream to select. It is a no-op if None. | required |
Returns:
| Name | Type | Description |
|---|---|---|
StreamContext | StreamContext | A context manager that restores the previously selected stream on exit. |
set_stream(stream) ¶
Select a stream for all subsequent work, and select its device as well.
This sets the stream for the remainder of the calling thread. Prefer the stream context manager, which restores the previous stream on exit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stream | Stream or None | The stream to select. It is a no-op if None. | required |
메모리¶
통계 API는 캐싱 할당기가 관리하는 디바이스 메모리를 표시합니다. 디바이스 메모리는 지연 할당하므로 rbln에 생성한 텐서는 디바이스 연산이 메모리를 실제 할당하기 전까지 통계에 포함되지 않습니다. 자세한 내용은 실행 방식에서 확인할 수 있습니다. Rebel100™ 카드 하나에는 칩렛 네 개로 구성된 칩 하나가 있으며 할당기는 칩렛별로 메모리를 추적합니다. memory_summary()와 memory_stats_per_chiplet()은 칩렛별 내역을 표시하고 나머지 통계는 칩렛 전체를 합산합니다(실행 방식 › Rebel100™과 ATOM™ 참고). mem_get_info()와 mem_get_info_per_chiplet()은 예외입니다. 현재 프로세스의 할당기가 확보한 메모리가 아니라 모든 프로세스에 걸쳐 커널 드라이버가 보는 디바이스 메모리를 표시합니다.
| API | torch.cuda 대응 API | 요약 |
|---|---|---|
torch.rbln.memory_allocated(device=None) | memory_allocated | 디바이스에서 텐서가 현재 사용하는 바이트 수입니다. |
torch.rbln.max_memory_allocated(device=None) | max_memory_allocated | 마지막 최댓값 초기화 이후 텐서가 사용한 바이트 수의 최댓값입니다. |
torch.rbln.memory_reserved(device=None) | memory_reserved | 캐시에 보관한 빈 블록을 포함하여 캐싱 할당기가 현재 관리하는 바이트 수입니다. |
torch.rbln.max_memory_reserved(device=None) | max_memory_reserved | 캐싱 할당기가 관리한 바이트 수의 최댓값입니다. |
torch.rbln.memory_stats(device=None) | memory_stats | allocated.current, allocated.peak, reserved.current, active.peak 같은 점으로 구분한 키를 사용하는 할당기 통계 사전입니다. |
torch.rbln.memory_stats_per_chiplet(device=None) | — | 같은 통계를 칩렛별로 나누며 각 키에는 npu.<n>.chiplet.<c>. 접두사가 붙습니다. 합산 통계에는 드러나지 않더라도 메모리 사용량이 가장 큰 칩렛에서 메모리가 부족해질 수 있습니다. |
torch.rbln.memory_summary(device=None) | memory_summary | 논리 디바이스의 NPU와 칩렛마다 한 행씩 표시하는, 텍스트 형식의 할당기 통계 표입니다. |
torch.rbln.mem_get_info(device=None) | mem_get_info | 드라이버가 모든 프로세스에 걸쳐 보고하는 디바이스 메모리 (free, total) 바이트 값입니다. rbln의 torch.accelerator.get_memory_info와 같은 값이며 total은 카드의 명목 메모리보다 작습니다. RBLN 디바이스가 없거나 더미 디바이스이거나 설치된 드라이버가 조회를 지원하지 않으면 예외가 발생합니다. |
torch.rbln.mem_get_info_per_chiplet(device=None) | — | 드라이버가 보고하는 칩렛별 값(npu.<n>.chiplet.<c>.{total,used,free,largest_free,largest_free_huge})과 NPU별 값(npu.<n>.{total,used,free,granularity,huge_granularity})입니다. npu.<n>은 물리 NPU ID가 아니라 논리 디바이스 안의 NPU 위치입니다. 연속 버퍼 크기는 한 칩렛의 largest_free로 제한되며 디바이스 전체의 free만으로는 이 제한을 알 수 없습니다. |
torch.rbln.reset_peak_memory_stats(device=None) | reset_peak_memory_stats | 최댓값 카운터를 초기화합니다. |
torch.rbln.reset_accumulated_memory_stats(device=None) | reset_accumulated_memory_stats | 누적 카운터를 초기화합니다. |
torch.rbln.empty_cache(device=None) | empty_cache | 사용하지 않는 캐시 디바이스 메모리를 반환합니다. 컴파일 프로그램의 웜 캐시와 뷰 레시피 캐시도 비우므로 호출자가 더 이상 보유하지 않는 메모리를 모두 반환합니다. |
torch.rbln.bind_device_memory(tensor) | — | 첫 사용을 기다리지 않고 텐서의 디바이스 메모리를 즉시 할당합니다. 집합 통신 라이브러리나 직접 스토리지 DMA처럼 PyTorch 연산자를 거치지 않고 디바이스 메모리를 읽는 소비자에게 버퍼를 전달하기 전에 필요합니다. 텐서는 스토리지 전체를 포함해야 합니다. |
torch.rbln.set_device_layout_like(target, ref) | — | 복사 없이 target의 디바이스 할당 레이아웃을 디바이스에 상주하는 텐서 ref와 맞춰 이후 두 텐서 간 디바이스 복사가 빠른 경로를 사용하도록 합니다. 두 텐서는 같은 디바이스와 dtype의 RBLN 텐서여야 합니다. |
torch.rbln.huge_host_empty(nbytes) | — | 디바이스가 스테이징 복사 없이 DMA할 수 있는 2 MiB 정렬 호스트 버퍼를 할당하며 페이지도 미리 확보합니다. 0으로 채운 1차원 uint8 CPU 텐서를 반환합니다. Transparent huge page는 가능한 범위에서 요청합니다. |
torch.rbln.offload() | — | 블록 안에서 할당한 RBLN 텐서의 호스트 영역에 파일 오프로딩을 활성화하는 컨텍스트 관리자입니다. 중첩 블록은 참조 횟수로 관리합니다. 파일은 RBLN_OFFLOAD_DIR에 저장합니다(기본값 $HOME/.cache/rbln_cache/offload). |
torch.rbln.release_offload_temp_storage() | — | 현재 프로세스의 임시 오프로딩 파일을 제거합니다. 런타임 자체 정리 전에 종료될 수 있는 종료 경로에서 호출합니다. 이후 오프로딩한 텐서를 사용하면 안 됩니다. 제거한 파일 수를 반환합니다. |
memory_allocated(device=None) ¶
Return the current device memory occupied by tensors in bytes for a given device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | int, str, or torch.device | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Name | Type | Description |
|---|---|---|
int | int | The current memory occupied by tensors in bytes. |
Note
This function reflects device memory only. For information about lazy memory allocation, see memory_stats().
max_memory_allocated(device=None) ¶
Return the maximum device memory occupied by tensors in bytes for a given device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | int, str, or torch.device | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Name | Type | Description |
|---|---|---|
int | int | The maximum memory occupied by tensors in bytes. |
Note
This function reflects device memory only. For information about lazy memory allocation, see memory_stats().
memory_reserved(device=None) ¶
Return the current device memory managed by the caching allocator in bytes for a given device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | int, str, or torch.device | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Name | Type | Description |
|---|---|---|
int | int | The current memory managed by the caching allocator in bytes. |
Note
This function reflects device memory only. For information about lazy memory allocation, see memory_stats().
max_memory_reserved(device=None) ¶
Return the maximum device memory managed by the caching allocator in bytes for a given device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | int, str, or torch.device | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Name | Type | Description |
|---|---|---|
int | int | The maximum memory managed by the caching allocator in bytes. |
Note
This function reflects device memory only. For information about lazy memory allocation, see memory_stats().
memory_stats(device=None) ¶
Return a dictionary of device memory allocator statistics for a given device.
The returned dictionary contains various memory statistics including:
allocated.current: Current memory occupied by tensorsallocated.peak: Peak memory occupied by tensorsallocated.total_allocated: Total memory allocated to tensors (cumulative)allocated.total_freed: Total memory freed from tensors (cumulative)reserved.current: Current memory managed by the caching allocatorreserved.peak: Peak memory managed by the caching allocatorreserved.total_allocated: Total memory allocated by the caching allocator (cumulative)reserved.total_freed: Total memory freed by the caching allocator (cumulative)active.current: Current size of blocks in use (may differ from allocated due to block granularity)active.peak: Peak size of blocks in usecached.current: Current size of cached blocks available for reusecached.peak: Peak size of cached blocksnum_alloc_retries: Number of allocation retries after cache flushnum_ooms: Number of out-of-memory errorsnum_device_alloc: Number of device memory acquisitionsnum_device_free: Number of device memory releases
Lazy Tensor Memory Allocation: All memory-related functions in this module (including memory_allocated(), memory_reserved(), max_memory_allocated(), max_memory_reserved(), and this function) reflect device memory only, not CPU memory.
RBLN tensors use lazy memory allocation for device memory. When you create a tensor on an RBLN device:
- The tensor is initially allocated in CPU memory immediately upon creation
- Device memory allocation is deferred until the tensor is actually needed for device operations
- When a device operation is required, the tensor data is lazily transferred from CPU to device memory
This lazy allocation strategy means that memory statistics may be lower than expected immediately after tensor creation until the tensors are used in device computations. Device memory statistics will increase when tensors are materialized on the device during actual computation.
The statistics also include lazy tensor related metrics, which provide insights into the memory management for tensors that have not yet been materialized on the device. The specific lazy tensor statistics fields may vary depending on the implementation version.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | int, str, or torch.device | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Type | Description |
|---|---|
Dict[str, int] | Dict[str, int]: A dictionary containing device memory statistics. Note that these statistics reflect device memory only (not CPU memory) and may not include memory for tensors that have not yet been transferred to the device. |
Note
To see accurate device memory usage, check statistics after performing operations that require the tensors to be materialized on the device, as device memory is allocated lazily when needed. This applies to all memory-related functions in this module.
memory_stats_per_chiplet(device=None) ¶
Return memory allocator statistics broken down per chiplet.
Same keys as memory_stats(), each prefixed with npu.<n>.chiplet.<c>. -- e.g. npu.0.chiplet.0.allocated.current. A device runs out on its heaviest chiplet, which the aggregate memory_stats() hides.
npu.<n> is the n-th physical NPU of this logical device (RBLN_NPUS_PER_DEVICE / RBLN_DEVICE_MAP), not a physical NPU id; a 1:1 mapping yields npu.0 only. Same scope as memory_stats().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | Optional[Union[int, str, device]] | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Type | Description |
|---|---|
Dict[str, int] | Dict[str, int]: A dictionary containing per-chiplet memory statistics. |
memory_summary(device=None) ¶
Return a human-readable printout of the current memory allocator statistics.
Rows are per (NPU, chiplet), so an imbalance is visible at a glance. The scope line under the title names what the numbers cover: they are this process's allocator, not the NPU's occupancy (see memory_stats()). The npu column is the physical NPU id as torch.rbln.device_summary() prints it: relative to RBLN_VISIBLE_DEVICES, so it differs from rbln-smi when that variable is set. A logical device grouping several NPUs (RBLN_NPUS_PER_DEVICE / RBLN_DEVICE_MAP) gets one row per NPU.
Peaks are tracked per chiplet, so the peak columns of the total row bound the joint peak from above rather than reporting it. memory_stats() carries the exact joint peak.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | Optional[Union[int, str, device]] | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Name | Type | Description |
|---|---|---|
str | str | The formatted table, or a short notice when no stats are available. |
mem_get_info(device=None) ¶
Return the free and total device DRAM of device in bytes, as (free, total).
Same contract as torch.cuda.mem_get_info, and what torch.accelerator.get_memory_info reports for rbln: the NPU's figures as the kernel driver sees them, across every process, not this process's caching allocator, which memory_stats() covers. total is the pool the driver can hand out, so it sits below the part's nominal DRAM. A logical device spanning several physical NPUs (RBLN_NPUS_PER_DEVICE / RBLN_DEVICE_MAP) reports their sum; one tensor still lives on one NPU. The result is a reading, not a reservation: another process may allocate right after.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | Optional[Union[int, str, device]] | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Type | Description |
|---|---|
Tuple[int, int] | Tuple[int, int]: |
Raises:
| Type | Description |
|---|---|
RuntimeError | if there is no RBLN device, the device is a dummy device, or the installed driver does not provide the device memory query. |
mem_get_info_per_chiplet(device=None) ¶
Return the driver's device DRAM usage of device broken down per chiplet, in bytes.
Same figures as mem_get_info() before summation, keyed like memory_stats_per_chiplet(): npu.<n>.chiplet.<c>.{total,used,free,largest_free, largest_free_huge} for each chiplet, and npu.<n>.{total,used,free,granularity, huge_granularity} for each physical NPU of the logical device. npu.<n> is the NPU's position within the logical device, not a physical NPU id.
Each chiplet allocates from its own pool, so a physically contiguous buffer is bounded by one chiplet's largest_free (largest_free_huge for the huge granule; 0 where the part has none), which the device-wide free hides. largest_free may exceed free in the same reply: both are estimates from a lock-free walk.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | Optional[Union[int, str, device]] | The device to query. If None, uses the current device. Defaults to None. | None |
Returns:
| Type | Description |
|---|---|
Dict[str, int] | Dict[str, int]: A map from key to bytes. |
Raises:
| Type | Description |
|---|---|
RuntimeError | under the same conditions as |
reset_peak_memory_stats(device=None) ¶
Reset the "peak" stats tracked by the caching allocator for a given device.
This function resets the peak values to their current values for the following stats:
allocated.peak: Reset toallocated.currentreserved.peak: Reset toreserved.currentactive.peak: Reset toactive.currentcached.peak: Reset tocached.current
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | int, str, or torch.device | The device to reset stats for. If None, uses the current device. Defaults to None. | None |
reset_accumulated_memory_stats(device=None) ¶
Reset the "accumulated" (historical) stats tracked by the caching allocator for a given device.
This function resets the following accumulated stats to zero:
allocated.total_allocatedallocated.total_freedreserved.total_allocatedreserved.total_freednum_alloc_retriesnum_oomsnum_device_allocnum_device_free
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | int, str, or torch.device | The device to reset stats for. If None, uses the current device. Defaults to None. | None |
empty_cache(device=None) ¶
Release all unoccupied cached memory currently held by the caching allocator so that those can be used in other application.
Note that only unfragmented (non-split) blocks can be released; fragmented blocks that have been split will remain in the cache until they can be coalesced.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device | int, str, or torch.device | The device to empty cache for. If None, uses the current device. Defaults to None. | None |
bind_device_memory(tensor) ¶
Materialize tensor's device allocation instead of leaving it lazy.
A device allocation reserves a virtual address and materializes the physical memory behind it on first use through a torch op. A consumer that reads those physical buffers out of band, such as a collective library or direct storage (NVMe) DMA, never runs such an op, so it would find nothing there. Call this after allocating a buffer you are handing to one.
The region is laid out flat and 1:1 with no dtype transform, on the device's main node, which is what a consumer treating it as bytes expects. Use set_device_layout_like() instead when the layout has to match another tensor's. Binding an already-bound region is allowed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tensor | Tensor | An RBLN tensor covering its whole storage: contiguous, with zero storage offset. A view that still spans the whole storage is fine; a slice or an interior view is not, since its address is not the allocation's. | required |
Raises:
| Type | Description |
|---|---|
RuntimeError | if |
set_device_layout_like(target, ref) ¶
Configure target's device-allocation layout to match ref (no copy).
Both must be RBLN tensors with the same dtype, on the same device, and each covering its whole storage. ref must be device-resident. target adopts ref's layout and dtype while keeping its own size; no data is transferred. A subsequent device-to-device copy between target and ref then stays on the fast path.
Typical use: make a host→device staging buffer match a KV cache's layout so the bulk upload and the per-slot device-to-device scatter are both fast.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target | Tensor | The RBLN tensor whose device-allocation layout is configured. | required |
ref | Tensor | The device-resident RBLN tensor whose layout | required |
Raises:
| Type | Description |
|---|---|
RuntimeError | if either tensor is not an RBLN tensor covering its whole storage, if the two are on different devices or have different dtypes, or if |
huge_host_empty(nbytes) ¶
Allocate a host buffer the device can DMA into without a staging copy.
An ordinary CPU tensor is 64 B aligned; the runtime's copy path stages any host address that is not page aligned through a bounce buffer, and even an aligned one pays a page fault per 4 KiB the first time the runtime resolves its host addresses, a cost that lands in the transfer, not in setup. This returns 2 MiB-aligned memory instead, prefaulted, so neither happens. It also asks for transparent huge pages, but that part is best effort: with THP disabled the alignment still holds and nothing is huge-page backed.
The buffer is released when the last reference to the returned tensor (or to a view of it) goes away.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nbytes | int | Size of the buffer in bytes. Must be in | required |
Returns:
| Type | Description |
|---|---|
Tensor | torch.Tensor: A zero-filled 1-D |
Raises:
| Type | Description |
|---|---|
TypeError | if |
ValueError | if |
MemoryError | if the allocation fails. |
offload() ¶
Context manager that enables RBLN file offloading for its scope.
Inside the with block, the process-wide file offloading switch is on, so host-side regions backing RBLN tensors allocated within the block may be paged out to disk. Use this around code paths that allocate large host-resident tensors (for example, KV-cache initialization) where host RAM pressure matters.
Nested offload blocks are tracked via a thread-safe depth counter; the switch is flipped back off only when the outermost context exits.
release_offload_temp_storage() ¶
Remove this process's file offloading temp files and directories.
offload() writes into a per-process directory under RBLN_OFFLOAD_DIR (default $HOME/.cache/rbln_cache/offload) that the runtime removes on teardown. Call this on a shutdown path that may be killed first. Offloaded tensors must not be used afterwards.
Returns:
| Name | Type | Description |
|---|---|---|
int | int | The number of temp files removed. |
Explain과 프로파일링¶
torch.rbln.explain()은 실행 시간을 측정하는 프로파일러가 아니라 숨은 오버헤드를 설명하는 도구입니다. 지정한 영역의 호스트 왕복 전송, CPU fallback, 재컴파일을 집계하고 각각의 원인을 표시합니다. 실제 경과 시간은 torch.profiler로 측정해야 합니다. Rebel100™ NPU에서는 런타임을 시작하기 전에 RBLN_PROFILER=1을 설정하면 Kineto 브리지가 RBLN 디바이스 활동을 트레이스에 전달합니다. ATOM™ NPU에서는 브리지가 비활성 상태로 유지되며 호스트 활동만 표시됩니다(환경 변수 › 프로파일링 참고).
| API | 반환값 | 요약 |
|---|---|---|
torch.rbln.explain(with_stack=False) | RBLNExplain | 지정한 영역을 감싸는 컨텍스트 관리자입니다. with_stack=True이면 연산자별 첫 fallback, 재컴파일, 호스트 왕복 전송의 Python 호출 위치를 기록합니다. trace=는 더 이상 권장하지 않는 with_stack=의 별칭입니다. |
torch.rbln.explain_steady(fn, *, warmup=2, return_cold=False, as_diff=False, with_stack=False) | RBLNExplain, (cold, warm), 또는 RBLNDiff | 한 영역 안에서 fn을 한 번 호출하고 warmup회 더 호출한 뒤 두 번째 영역 안에서 한 번 더 호출하여 첫 호출 비용과 정상 상태를 구분합니다. fn을 이전에 실행하지 않았으며 매 호출 같은 작업을 한다고 가정합니다. as_diff=True이면 신호별 변화를 반환합니다. |
RBLNExplain.report() | str | 마커로 시작하는 보고서입니다. [clean] 또는 [overhead: N signals], Count, Bytes, Note 열의 신호 표, 신호별 상세 블록을 포함합니다. |
RBLNExplain.verdict() | dict | clean 플래그와 reasons를 반환하며 CI 판정에 사용할 수 있습니다. |
RBLNExplain.dump() | dict | 모든 신호를 원시 수치로 반환합니다. |
RBLNExplain.help(signal=None) | str | 특정 신호 또는 발생한 모든 신호의 전체 설명을 반환합니다. |
RBLNExplain.diff(other) | RBLNDiff | 지정한 두 영역을 비교합니다. |
RBLNExplain.start() / stop() | — | with 대신 영역의 시작과 끝을 직접 지정합니다. |
torch.rbln.profile, torch.rbln.RBLNProfile | 별칭 | 이전 코드와 호환되도록 남겨 둔 explain과 RBLNExplain의 별칭입니다. |
보고하는 신호는 다음과 같습니다.
| 신호 | 의미 | 일반적인 안내 |
|---|---|---|
host_bounce/* | 디바이스 간 경로 대신 호스트 왕복 전송(디바이스 → 호스트 → 디바이스)을 사용한 복사입니다. Bytes는 호스트 경로의 전송량이며 >> physical d2h 행은 디바이스 경계를 넘은 바이트가 있는지 표시합니다. | 텐서를 연속 형태로 만들거나 디바이스 간 복사 경로 사용 |
runtime/v2v_slow | 디바이스 간 복사에 느린 경로를 사용했습니다. 로드한 librbln.so가 런타임 카운터를 제공할 때만 관찰할 수 있습니다. | set_device_layout_like로 레이아웃 맞춤 |
dispatch/cpu_fallback | CPU에서 실행한 연산자를 연산자별 횟수와 why: 행(dtype-not-fp16, nan/inf input, all-scalar inputs), 빠른 경로 핸들러가 없는 연산자 목록으로 표시합니다. 디바이스 커널이 없는 연산자와 CPU에 고정된 연산자는 집계하지 않지만 fallback 로그에는 이름을 표시합니다. | 지원하는 dtype 사용 또는 torch.compile로 실행 |
dispatch/recompile | 영역 안에서 연산자나 그래프를 다시 컴파일했습니다. | shape와 dtype을 일정하게 유지 |
보고서 머리글에는 영역의 경과 시간, 디바이스 예약 메모리의 최댓값, 호출 유형별 런타임 내부 소요 시간도 표시합니다. 프로세스의 스레드 수가 CPU 코어 수보다 많으면 경고를 표시합니다.
보고서를 해석할 때는 다음 세 가지 규칙을 따라야 합니다.
- 한 번에 하나의 영역만 사용해야 합니다. 영역은 중첩되거나 겹치면 안 되며 하나의 스레드에서 유지해야 합니다. 두 번째 영역을 열면 예외가 발생합니다.
- 컴파일된 순전파만 감싸지 말고 단계 전체를 감싸야 합니다. 컴파일된 그래프는 구조상 clean이며 숨은 작업은 그래프 주변의 eager 코드에 있습니다.
! host oversubscription행은 프로세스의 스레드 수가 코어 수보다 많다는 뜻입니다. 이 경우 영역 안의 호스트 지연은 개별 연산자보다 경합 때문에 발생할 수 있습니다. 연산자별 수치를 읽기 전에 affinity나OMP_NUM_THREADS를 조정해야 합니다. 머리글에 런타임 신호가 노출되지 않는다고 표시되면runtime/v2v_slow행이 없더라도 빠른 경로를 사용했다는 근거가 되지 않습니다.
RBLNExplain ¶
A hidden-overhead explain region. Create one with explain() and use it as a context manager.
Regions must not overlap: the underlying counters and timers are process-global, so opening a nested or concurrent region raises a RuntimeError. The counters are also process-wide, meaning the values include activity from every thread that ran during the region, not only the calling thread.
report() ¶
Render the human-readable report: a [clean] / [overhead: N signals] marker, a torch.profiler-style signal table with a Note column carrying the remedy for each actionable row, and per-signal detail blocks.
Returns:
| Name | Type | Description |
|---|---|---|
str | str | The report text. Print this. |
verdict() ¶
Summarize the region as a clean flag plus the factual reasons behind it.
The result is intended for CI gating. clean states whether any hidden signal fired; it is not a severity grade.
Returns:
| Type | Description |
|---|---|
Dict[str, Any] | Dict[str, Any]: A dictionary containing |
dump() ¶
Return every signal as raw numbers, for programmatic checks.
Returns:
| Type | Description |
|---|---|
Dict[str, Any] | Dict[str, Any]: Host-bounce counts and bytes by site, dispatch counters (CPU fallbacks, recompilations, warm hits), per-operator breakdowns, runtime residency, and the region wall time. |
start() ¶
Open the region manually instead of entering with. Returns self.
stop() ¶
Close a region opened with start(). Returns self.
help(signal=None) ¶
Return the full remedy text for the signals that fired in the region.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signal | Optional[str] | A signal name, either the bare cause or the report label such as | None |
Returns:
| Name | Type | Description |
|---|---|---|
str | str | The remedy text. |
diff(other) ¶
Compare this region with a later one, for example a first call against a steady-state call. A region records only what happened inside it, so it cannot separate one-time cost from recurring cost by itself; placing two regions is how that structure is supplied. See RBLNDiff.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other | RBLNExplain | The later region. The comparison runs from | required |
Returns:
| Name | Type | Description |
|---|---|---|
RBLNDiff | RBLNDiff | The signal-by-signal change between the two regions. |
RBLNDiff(a, b) ¶
The signal-by-signal change between two regions, from a to b.
A region records only what happened inside it, so on its own it cannot separate a one-time cost from a recurring one. Placing the two regions, for example around a first call and a later steady-state call, supplies that structure. The diff reports only what changed between the two points: a signal that is zero in b did not recur, and a signal that persists is overhead that recurs between them. It makes no claim about anything outside the two regions.
Build the diff of two closed regions a and b; RBLNExplain.diff() calls this.
dump() ¶
Return the diff as raw numbers.
The dictionary has the following shape:
a_bytes and b_bytes are present for byte-carrying signals only, so a recurring cost can be ranked by host-traffic volume as well as by count.
Returns:
| Type | Description |
|---|---|
dict[str, Any] | dict[str, Any]: The diff as a dictionary. |
report() ¶
Human-readable diff table with one row per signal and a >> persists marker on the recurring ones.
explain(with_stack=False, *, trace=None) ¶
Return a hidden-overhead explain region, usable as a context manager.
A normal PyTorch operation can silently round-trip the host (NPU to CPU to NPU), fall back to a CPU kernel, or trigger a recompilation. None of that is visible in your Python code. explain() counts those hidden events, attributes a cause and a remedy to each, and renders a torch.profiler-style report.
This is a hidden-overhead explainer, not a timing profiler: it does not report how long a forward pass took or which layer is slow. A region with no hidden overhead can still be slow because it is device-compute bound. For wall-clock timing, use torch.profiler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
with_stack | bool | If True, capture the Python call site of each fallback, recompilation, and host bounce (deduplicated per operator) and show it in the report. Off by default, so a plain region adds nothing to any code path. Defaults to False. | False |
Returns:
| Name | Type | Description |
|---|---|---|
RBLNExplain | RBLNExplain | A region object usable as a context manager. |
Example
Note
torch.rbln.profile and torch.rbln.RBLNProfile are backward-compatible aliases of explain and RBLNExplain. The trace= keyword is a deprecated alias for with_stack=.
explain_steady(fn, *, warmup=2, return_cold=False, as_diff=False, with_stack=False, trace=None) ¶
Place two explain regions around fn: one around the first call it makes and one around a later call after warmup more calls.
The helper only automates region placement. Its cold and warm labels mean the first call it made and a later call it made, nothing more. Reading the result as one-time versus recurring cost rests on two assumptions that the caller has to guarantee, because the helper cannot verify them:
fnwas not run or compiled before this call. Otherwise the one-time cost happened before the cold sample and is not captured.- Every
fn()call does the same work. Otherwise the recompiles in the warm sample come from different shapes, not from recurring overhead.
When both hold, cold.diff(warm) shows what changed: signals gone in the warm region did not recur across the two calls, and signals that persist are the recurring overhead. The helper is plain Python orchestration and adds nothing to the hot path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn | Callable[[], Any] | The callable to observe. It is called | required |
warmup | int | Number of calls between the two regions. Defaults to 2. | 2 |
return_cold | bool | Return | False |
as_diff | bool | Return | False |
with_stack | bool | Record the first Python call site per operator in both regions. Defaults to False. | False |
trace | Optional[bool] | Deprecated alias for | None |
Returns:
| Type | Description |
|---|---|
RBLNExplain | tuple[RBLNExplain, RBLNExplain] | RBLNDiff | RBLNExplain | tuple[RBLNExplain, RBLNExplain] | RBLNDiff: The warm region by default; |
컴파일된 프로그램¶
torch.compile은 백엔드가 반환한 callable을 Dynamo 코드 캐시에 보관하므로 사용자 코드는 컴파일 결과의 핸들을 직접 받지 못합니다. torch.rbln.capture_programs()는 열린 범위 안에서 rbln 백엔드가 만드는 모든 프로그램을 빌드 순서로 기록합니다. torch.profiler.profile()이 범위 안의 이벤트를 수집하는 것과 같은 방식입니다. 캡처한 각 프로그램은 입력과 출력을 설명하며 동적 shape 텐서의 디바이스 레이아웃도 포함합니다.
| API | 요약 |
|---|---|
torch.rbln.capture_programs() | list[CompiledProgram]을 제공하는 컨텍스트 관리자이며 torch.compile이 백엔드를 호출할 때 목록을 채웁니다. 중첩 범위는 각각 열려 있는 동안 빌드한 모든 프로그램을 받습니다. 범위는 thread-local이므로 연 스레드에서 수행한 컴파일만 기록합니다. |
torch.rbln.CompiledProgram | 컴파일된 그래프 하나입니다. name(예: "0/0"인 Dynamo 컴파일 ID), device, runtime(callable의 실행 핸들), input_specs, output_specs를 포함합니다. |
torch.rbln.InputSpec, torch.rbln.OutputSpec | 입력 또는 출력 하나입니다. shape, dtype, physical_placement를 포함하며 입력에는 name도 있습니다. 런타임이 입력을 받고 출력을 반환하는 순서대로 나열합니다. |
torch.rbln.PhysicalPlacement | 동적 shape 입력 또는 출력의 디바이스 레이아웃입니다. 물리 shape, dtype, shards를 포함합니다. 정적 shape 입력과 출력에서는 None입니다. |
torch.rbln.ShardPlacement | 해당 레이아웃의 shard 하나입니다. node_id, chiplet_id, slice_shape를 포함합니다. |
이 클래스들은 RBLN Compiler에 구현되어 있으며 처음 접근할 때 로드됩니다. import torch만으로는 컴파일러를 로드하지 않습니다. 현재 torch-rbln 릴리스와 짝을 이루는 rebel-compiler 릴리스가 필요합니다(설치 참고).
CompiledProgram(name, device, runtime, input_specs, output_specs) dataclass ¶
One graph the rbln backend built for torch.compile.
Attributes:
| Name | Type | Description |
|---|---|---|
name | str | Dynamo's compile id for the graph ( |
device | Optional[device] | The logical RBLN device the graph's input tensors live on, where the runtime allocates its outputs; |
runtime | Any | The execution handle behind the compiled callable. |
input_specs | Tuple[InputSpec, ...] | The graph's inputs, in the order the runtime takes them. |
output_specs | Tuple[OutputSpec, ...] | The graph's outputs, in the order the runtime returns them. |
InputSpec(name, shape, dtype, physical_placement=None) dataclass ¶
An input of a compiled program.
Attributes:
| Name | Type | Description |
|---|---|---|
name | str | The input's name in the compiled model; may be empty. |
shape | Tuple[int, ...] | The compiled extents. |
dtype | dtype or dtype | The element type. |
physical_placement | Optional[PhysicalPlacement] | The device layout of a dynamic-shape input; |
OutputSpec(shape, dtype, physical_placement=None) dataclass ¶
An output of a compiled program. The fields read as in InputSpec.
Attributes:
| Name | Type | Description |
|---|---|---|
shape | Tuple[int, ...] | The compiled extents. |
dtype | dtype or dtype | The element type. |
physical_placement | Optional[PhysicalPlacement] | The device layout of a dynamic-shape output; |
PhysicalPlacement(shape, dtype, shards) dataclass ¶
Device layout of a dynamic-shape input or output: its physical shape, dtype, and the shards it is split into.
A static dimension is a plain int. A dynamic dimension is an expression written as nested tuples: ("symbol", name) is the dynamic-shape variable name, whose value is the size of the input dimension compiled as dynamic; ("prod", e1, e2, ...) and ("sum", e1, e2, ...) are the product and sum of their operands. Binding the variables to the current input sizes gives the concrete extent: [2, ("symbol", "s0"), 8] with s0 == 4 is [2, 4, 8]. The dynamic axis is never split across shards, so it appears as the same symbol in shape and in every shard's slice_shape.
Attributes:
| Name | Type | Description |
|---|---|---|
shape | tuple | The physical shape on the device. |
dtype | str | The element type on the device. |
shards | Tuple[ShardPlacement, ...] | The shards the tensor is split into. |
ShardPlacement(node_id, chiplet_id, slice_shape) dataclass ¶
One device shard of a tensor: which (node, chiplet) holds it and the extent it holds.
Attributes:
| Name | Type | Description |
|---|---|---|
node_id | int | The node that holds the shard. |
chiplet_id | int | The chiplet that holds the shard. |
slice_shape | tuple | The extent of the shard, one entry per dimension. A static dimension is an |
capture_programs() ¶
Context manager that records the programs the rbln backend builds inside it.
torch.compile keeps the callable a backend returns inside Dynamo's code cache, so the caller never receives a handle to what was compiled. This scope yields a list that fills, in build order, as torch.compile invokes the backend, the way torch.profiler.profile() collects the events inside it.
Every open scope receives each program, so nested scopes see the same programs; an inner scope simply sees fewer. The scope is thread-local: it records the backend calls made from the thread that opened it.
Returns:
| Type | Description |
|---|---|
Iterator[List[CompiledProgram]] | Iterator[List[CompiledProgram]]: The list of captured programs, as the |
Example
진단¶
| 명령 | 요약 |
|---|---|
python -m torch_rbln.diagnose | 라이브러리 검색 경로, 패키지 위치, 모든 librbln.so 후보와 실제 로드한 라이브러리, rebel ABI 판정 결과를 출력합니다. |
지원 연산¶
eager 실행에서 연산자는 두 가지 구현 경로로 RBLN NPU에 도달합니다. 다음 표는 각 연산자를 개별적으로 디스패치하는 eager 실행의 지원 범위를 설명합니다. torch.compile(backend="rbln")로 컴파일한 그래프 안의 지원 범위는 RBLN Compiler가 결정하며, 지원하는 연산 - 파이토치에 정리되어 있습니다.
| 경로 | 실행 방식 | 목록 출처 |
|---|---|---|
| 컴파일 커널 | 첫 사용 시 RBLN Compiler가 연산자의 shape와 dtype에 맞춰 컴파일하고 캐시에 저장합니다. 바인딩은 빌드 시 aten/src/ATen/native/native_functions.yaml에서 생성합니다. | native_functions.yaml(dispatch: PrivateUse1) |
| 네이티브 커널 | libtorch_rbln.so의 C++ 커널이 런타임을 통해 복사, 뷰, 인덱싱 연산을 직접 수행합니다. 컴파일하지 않습니다. | aten/src/ATen/native/RBLNRegisterOps.cpp |
Dtype 정책¶
| Dtype | 컴파일 커널 | 네이티브 커널 |
|---|---|---|
float16, bfloat16 | 디바이스에서 실행 | 디바이스에서 실행 |
float32, 정수, bool, 기타 | CPU fallback | 디바이스에서 실행(복사, 뷰, 인덱싱은 dtype에 의존하지 않음) |
Scaled dot-product attention도 같은 두 디바이스 dtype을 사용합니다. 이번 릴리스에는 autocast dtype이 등록되지 않아 torch.autocast는 rbln에 적용되지 않습니다. 혼합 dtype 입력의 타입 승격 결과가 디바이스 dtype 범위를 벗어나면 CPU로 fallback합니다.
컴파일 연산자¶
다음 연산자는 NPU 커널로 실행됩니다. 지원하는 입력 조건과 제한 사항은 비고에 표시합니다.
| 연산자 | Torch API | 비고 |
|---|---|---|
aten::abs | torch.abs | |
aten::add | torch.add, + | alpha 지원 |
aten::sub | torch.sub, - | alpha 지원 |
aten::mul | torch.mul, * | |
aten::div | torch.div, / | |
aten::neg | torch.neg, 단항 - | |
aten::pow | torch.pow, ** | 스칼라 지수만 지원. 텐서 지수 또는 스칼라 밑은 CPU에 고정 |
aten::rsqrt | torch.rsqrt | |
aten::log | torch.log | |
aten::ceil | torch.ceil | |
aten::floor | torch.floor | |
aten::clamp | torch.clamp | 스칼라 경계값 지원. 텐서 경계값은 CPU에 고정 |
aten::sigmoid | torch.sigmoid | |
aten::silu | torch.nn.functional.silu | |
aten::_softmax | torch.softmax, torch.nn.functional.softmax | |
aten::mm | torch.mm, @ | |
aten::bmm | torch.bmm | |
aten::addmm | torch.addmm | |
aten::linear | torch.nn.functional.linear, torch.nn.Linear | |
aten::mean | torch.mean | |
aten::max, aten::min | torch.max, torch.min | 전체 축약 연산 지원. dim 축약 연산은 CPU에 고정 |
aten::maximum, aten::minimum | torch.maximum, torch.minimum | |
aten::eq, ne, lt, le, gt, ge | 비교 연산자 | |
aten::logical_not | torch.logical_not | |
aten::where | torch.where | |
aten::masked_fill_ | Tensor.masked_fill_, torch.masked_fill | |
aten::_scaled_dot_product_fused_attention_overrideable | torch.nn.functional.scaled_dot_product_attention | rbln 텐서에서 _fused_sdp_choice가 선택 |
네이티브 연산자¶
이 연산자들은 libtorch_rbln.so의 C++ 커널에서 런타임을 직접 호출합니다. 계산하는 대신 데이터를 이동하거나 설명하므로 모든 dtype에서 실행됩니다.
| 그룹 | 연산자 |
|---|---|
| 할당과 채우기 | empty, empty_strided, zero_, fill_(스칼라 값), clone, _efficientzerotensor, arange |
| 복사 | _copy_from, _copy_from_and_resize, _foreach_copy_, resize_, set_, _local_scalar_dense(.item()) |
| 뷰(메타데이터만 변경, 디바이스 작업 없음) | view, _unsafe_view, _reshape_alias, as_strided, alias, unfold |
| 연결과 반복 | cat(cat으로 분해되는 stack 포함), repeat_interleave |
| 인덱싱 | index_select, index_copy, 하나의 축에 정수 텐서 인덱스 하나를 사용하는 index(다른 형태는 커널 내부에서 CPU로 fallback) |
strided 뷰의 디바이스 간 copy_는 디바이스에서 처리합니다. 두 디바이스 경로와 호스트를 거치는 한 가지 경우는 실행 방식 › 뷰와 strided 복사에서 설명합니다.
CPU에 고정된 연산자¶
다음 연산자들은 CPU fallback 경로에 명시적으로 등록되어 있습니다. 디바이스에서 호스트로 복사한 뒤 호스트에서 실행하고 결과를 다시 디바이스로 복사합니다. 다른 fallback과 마찬가지로 INFO 수준의 로그를 남깁니다. 등록 자체가 없는 연산자만 제어하는 TORCH_RBLN_DISABLE_FALLBACK=unsupported_op의 영향을 받지 않습니다.
| 그룹 | 연산자 |
|---|---|
| 난수 생성 | uniform_, normal_, normal, random_, randperm, native_dropout |
| 원소별 연산 | sin, cos, exp, trunc, sign, sgn, signbit, relu, addcmul, fmod, clamp(텐서 경계값), pow(스칼라 밑 또는 텐서 지수), nan_to_num, isnan, isposinf, isneginf, isin, equal |
| 비트 및 논리 연산 | bitwise_and, bitwise_or, bitwise_xor, bitwise_not, logical_and, logical_or, logical_xor |
| 축약과 스캔 | sum(dim 목록), all, any, cumsum, count_nonzero, linalg_vector_norm, argmax, max.dim, min.dim, topk |
| 인덱싱과 scatter | gather, scatter, index_add, index_fill_, _index_put_impl_, put_, masked_scatter_, masked_select, nonzero, fill_(텐서 값) |
| Shape | flip, tril, triu, view_as_real |
| 정규화 | native_batch_norm |
| 선형대수 | _linalg_svd |
모델에서 자주 실행하는 경로에 CPU 고정 연산자가 있다면 디바이스 커널 구현 후보가 됩니다. 문제 보고를 통해 알려 주시기 바랍니다. 일부 연산자에는 이미 일반 boxed 디스패처를 생략하는 빠른 호스트 경로가 있습니다(정수 원소별 연산, 마지막 차원의 fp32 mean, fp32 pow(x, 2), fp32 rsqrt). fp32로 계산하는 RMSNorm 분산의 비용은 일반 fallback보다 작습니다.
표에 없는 연산자¶
- 복합 연산자인
torch.stack등은 앞의 연산자로 분해되며(stack→cat) 해당 경로를 따릅니다. - 여러 인덱스 텐서를 사용하는 고급 인덱싱(
t[:, idx_a, :, idx_b])은 네이티브index커널의 지원 범위에 포함되지 않으며 CPU에서 실행됩니다. - 비연속
out=텐서는 연속 버퍼에서 처리한 뒤 다시 복사하므로 디바이스 메모리 할당과 복사가 한 번씩 추가됩니다. 자주 실행하는 경로에는 연속out=을 전달하는 것을 권장합니다. torch.ops.rbln_custom_ops의 사용자 정의 연산자(paged attention 커널)는 RBLN vLLM 네이티브 경로의 내부 구현이며 공개 API가 아닙니다.