Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

공간 차원과 시간 차원

HostTensor<D, E>는 단일 매핑으로 물리적 표현을 완전히 나타냅니다. 디바이스 텐서는 매핑을 여러 전용 차원에 나누어 담습니다:

  • 공간 차원: Chip, Cluster, Slice는 하드웨어 계층 전반에 데이터를 분산합니다. 스트림 텐서에서는 Packet이 각 시간 반복 내 병렬 전달의 크기를 추가로 정합니다.
  • 시간 차원: Time은 스트림 텐서에서 전달 반복의 순서를 정합니다.

공간 차원

하드웨어 계층의 각 공간 수준은 텐서 타입에서 고유한 타입 매개변수를 가지며, 이를 통해 공간 병렬성이 가능해집니다. 각 수준의 모든 유닛은 동일한 매핑을 공유한다고 가정합니다.

아래 표기법은 물리적 차원을 가리키지만 공개 타입이나 생성자는 아닙니다. 공개 텐서 API와 뷰는 스토리지 모듈에 문서화되어 있습니다.

extern crate furiosa_opt_std;
use furiosa_opt_std::prelude::*;
use std::marker::PhantomData;
// Assumed throughout this page.
axes![A = 8, B = 512];

// HBM tensors
struct HbmTensor<D: Scalar, Chip: M, Element: M> {
    /* ... */
    _marker: PhantomData<(D, Chip, Element)>,
}

// SRAM tensors
// DM (Data Memory), TRF (Tensor Register File), and VRF (Vector Register File)
struct DmTensor<D: Scalar, Chip: M, Cluster: M, Slice: M, Element: M> {
    /* ... */
    _marker: PhantomData<(D, Chip, Cluster, Slice, Element)>,
}
struct TrfTensor<D: Scalar, Chip: M, Cluster: M, Slice: M, Lane: M, Element: M> {
    /* ... */
    _marker: PhantomData<(D, Chip, Cluster, Slice, Lane, Element)>,
}
struct VrfTensor<D: Scalar, Chip: M, Cluster: M, Slice: M, Element: M> {
    /* ... */
    _marker: PhantomData<(D, Chip, Cluster, Slice, Element)>,
}

HBM 텐서는 공간 병렬성을 위해 데이터를 여러 Chip에 분산합니다. 각 Chip은 자신이 맡은 데이터 부분을 동시에 처리합니다. 예를 들어, HbmTensor<bf16, m![A], m![B]>는 8 × 512 = 4096개의 요소를 8개의 Chip에 Chip당 512개씩 분산합니다. i번째 Chip의 j번째 요소는 텐서 인덱스 i![A: i, B: j]를 저장합니다.

SRAM 텐서 타입은 더 세분화된 병렬성을 위해 Cluster 및 Slice 차원을 추가합니다. TrfTensor에는 추가로 TRF 데이터를 Slice당 8개 레인에 분산하는 Lane 차원이 있습니다. 자세한 내용은 Contraction Engine을 참조하십시오.

HBM 텐서는 구체적인 주소를 가집니다. DM, TRF, VRF 텐서는 백엔드로부터 주소를 할당받을 수 있습니다. 호스트 텐서는 호스트 측 값으로 남습니다. 매핑 매개변수는 물리적 표현을 결정하며, 주소는 스토리지가 별도로 소유합니다.

제약 조건

  • Chip, Cluster, Slice 크기: 하드웨어 개수와 정확히 일치해야 합니다:

    단위개수제약 조건패딩 예시
    Chip시스템에 따라 다름Chip::SIZE == NUM_CHIPSm![1 # NUM_CHIPS]
    ClusterChip당 2개Cluster::SIZE == 2m![1 # 2]
    Slice256 / ClusterSlice::SIZE == 256m![X / N # 256]

    커널이 하드웨어가 제공하는 것보다 적은 수의 유닛을 사용할 때는 어떤 차원이든 #로 패딩할 수 있습니다. 예를 들어 type Cluster = m![1 # 2]는 활성 Cluster 1개와 패딩 전용 Cluster 1개를 사용하여 Chip당 Cluster 2개라는 하드웨어 요구 사항을 충족합니다.

    Note

    런타임은 Chip 단위(#[device(chip = N)])로 동작하므로 Chip이나 Cluster의 일부만 사용하는 것은 아직 지원되지 않습니다. 이 제한은 향후 릴리스에서 완화될 수 있습니다.

  • Element 크기: Element::SIZE * size_of::<D>()는 유닛당 SRAM 용량을 초과해서는 안 되며, 이 용량은 텐서 타입에 따라 다릅니다:

    타입단위제약 조건
    DmTensor512KB / SliceElement::SIZE * size_of::<D>() <= 512KB
    TrfTensor8KB / LaneLane::SIZE <= 8, Element::SIZE * size_of::<D>() <= 8KB
    VrfTensor8KB / SliceElement::SIZE * size_of::<D>() <= 8KB
  • Element 정렬: 디바이스 저장소 API는 주소에 정렬 제약 조건을 부과합니다. 모든 텐서에 하나의 주소 규칙이 적용된다고 가정하지 말고, 계층별 생성자와 백엔드 검사를 확인하십시오.

시간 차원

TuTensor는 Tensor Unit을 통해 스트림으로 흐르는 텐서 데이터를 나타냅니다. SRAM 타입과 동일한 Chip, Cluster, Slice 차원을 유지하며, 스트리밍을 위해 Time과 Packet을 추가합니다. Time은 시간 차원으로, 전달 반복의 순서를 정합니다. 공간 차원과 달리 Time에는 하드웨어가 부과하는 크기 제한이 없으며, 처리할 데이터의 양에 따라 커집니다. Packet은 각 Slice가 시간 반복마다 받는 요소 수를 결정하는 추가 공간 차원입니다.

#![allow(unused)]
fn main() {
#![feature(adt_const_params)]
extern crate furiosa_opt_std;
use furiosa_opt_std::prelude::*;
use std::marker::ConstParamTy;
use std::marker::PhantomData;
axes![N = 4, C = 64, H = 32, W = 32];

/// Pipeline stage.
/// `Vector` is intentionally absent: the Vector Engine uses a separate typestate
/// (`VectorBranchTensor` and friends) that tracks branch, ALU, and other Vector-specific state.
/// `Commit` is intentionally absent: once the Commit Engine writes results back to DM,
/// the data is at rest and the type becomes `DmTensor`, not `TuTensor`.
#[derive(PartialEq, Eq, ConstParamTy)]
enum Position {
    Begin,       // After the start of the pipeline
    Fetch,       // After the Fetch Engine
    Switch,      // After the Switch Engine
    Collect,     // After the Collect Engine
    Contraction, // After the Contraction Engine
    Reduce,      // After the Reduce Engine
    Cast,        // After the Cast Engine
    Transpose,   // After the Transpose Engine
}

struct TuTensor<
    'l,                // Lifetime tied to the Tensor Unit context
    const P: Position,
    D: Scalar,
    Chip: M,
    Cluster: M,
    Slice: M,
    Time: M,
    Packet: M,
> {
    /* ... */
     _marker: PhantomData<&'l (D, Chip, Cluster, Slice, Time, Packet)>,
}

type T<'l> = TuTensor<
    'l,
    { Position::Fetch }, // Fetch Engine's output
    bf16,
    m![1],           // Chip: single chip
    m![1],           // Cluster: single cluster
    m![C / 2],       // Slice: distribute 64 channels across 32 slices
    m![N, H, W],     // Time: iterate over batch (N) and spatial (H, W) dimensions
    m![C % 2],       // Packet: 2 channels per cycle
>;
}

타입 T는 전체 형태가 \(\{N=4, C=64, H=32, W=32\}\)인 텐서를 32개 Slice에 걸쳐 스트리밍합니다(Slice::SIZE = m![C / 2]::SIZE = 32). Time 차원(m![N, H, W])의 크기는 4 * 32 * 32 = 4096이며, 이는 시간 반복이 4,096회 있다는 뜻입니다. 각 시간 반복마다 Packet 차원 m![C % 2]는 각 Slice에 채널 2개를 전달합니다. 32개 Slice가 병렬로 동작하므로, 각 시간 반복은 총 32 * 2 = 64개 채널을 처리합니다.

NCHW 표현 추적

NCHW 예제에서는 배치를 네 개의 Chip에 분산하는 HBM 표현부터 시작해 표현이 어떻게 바뀌는지 추적할 수 있습니다:

#![allow(unused)]
fn main() {
extern crate furiosa_opt_std;
use furiosa_opt_std::prelude::*;
axes![N = 4, C = 64, H = 32, W = 32];
type Hbm = HbmTensor<bf16, m![N], m![C, H, W]>;
}

이를 활성 Chip 하나와 채널 두 개당 요소 Slice 하나로 구성된 DM으로 옮깁니다:

#![allow(unused)]
fn main() {
extern crate furiosa_opt_std;
use furiosa_opt_std::prelude::*;
axes![N = 4, C = 64, H = 32, W = 32];
type Dm = DmTensor<bf16, m![1], m![1], m![C / 2], m![N, H, W, C % 2]>;
}

위의 스트림 타입 T는 같은 채널 분할을 사용하지만, N, H, W는 Time에 두고 각 Slice의 두 채널은 Packet에 둡니다.

Index (N=1, C=17, H=3, W=5)를 추적해 봅시다:

  • HBM은 Chip 1을 선택하며, 요소 오프셋은 17 * 32 * 32 + 3 * 32 + 5 = 17,509입니다.
  • DM은 Slice 17 / 2 = 8을 선택하고, 요소 매핑은 N=1, H=3, W=5와 패킷 위치 17 % 2 = 1을 선택합니다.
  • 스트림은 Slice 8에서 Time = 1 * 32 * 32 + 3 * 32 + 5 = 1,125와 Packet = 1을 선택합니다.

값의 물리적 좌표는 단계마다 바뀌지만, 그 Index는 (1, 17, 3, 5)로 유지됩니다. 이렇게 매핑에서 표현으로 이어지는 경로를 추적할 수 있습니다. 텐서가 값을 가진다는 것이 무엇을 뜻하는지는 텐서 의미론에서 정의합니다.


원문 © FuriosaAI · Programming Tensor Contraction Processors · Apache License 2.0 · NOTICE
yeokja 한국어 번역 · Anthropic 사의 claude-sonnet-5 모델을 활용하여 번역되었으며 학습을 모두 비허용한 상태로 작업하였습니다 · 이 문서는 원문을 수정한 비공식 번역본이며 Apache License 2.0으로 제공합니다.