Rust borrow checker, CUDA에 도달 — 비용은 제로

NVIDIA·Hugging Face의 cuTile Rust: borrow-checked CUDA로 cuBLAS 96%, Grout 디코더는 B200 batch-1에서 vLLM과 동급.

Rust borrow checker, CUDA에 도달 — 비용은 제로
Share

GPU 커널은 오랫동안 어려운 선택을 강요해 왔다. CUDA C++의 순수한 속도를 택할 것인가, 아니면 CPU에서 Rust가 제공하는 메모리 안전성을 택할 것인가. 둘을 동시에 얻는 경우는 드물었다. NVIDIA와 Hugging Face의 새 논문은 이제 그 절충이 선택 사항이 됐다고 주장한다.

cuTile Rust가 CUDA 프로그래밍에 가져오는 것

cuTile Rust는 관용적인 Rust 커널을 CUDA Tile IR로 낮추는 도메인 특화 언어다. 동시에 Rust의 &/&mut 소유권 계약을 CPU→GPU 실행 경계 너머까지 유지한다. 이는 NVIDIA의 Melih Elibol, Jared Roesch, Isaac Gelado, Michael Garland와 Hugging Face의 Eric Buehler가 쓴 arXiv 논문 "Fearless Concurrency on the GPU" (arXiv:2606.15991, 2026년 6월 14일 게시)에서 소개됐다 . 주장은 좁지만 구체적이다. borrow check를 통과한 Rust GPU 코드가 측정 가능한 오버헤드 없이 벤더 라이브러리에 가까운 성능에 도달할 수 있다는 것이다.

간단히 말하면: cuTile Rust는 Rust의 borrow checker를 CUDA 커널까지 확장하는 NVIDIA/Hugging Face의 DSL이다. &/&mut 계약을 보존한 채 Tile IR로 낮춘다. 2026년 6월 논문에서는 GEMM에서 cuBLAS의 약 96%에 도달했고, batch-1 decode에서는 vLLM/SGLang과 맞먹었다. 측정된 비용 없이 안전성을 얻은 셈이다.

핵심 아이디어는 구조에 있다. 각 커널은 고정 크기 데이터 타일 위에서 단일 스레드 의미론으로 실행되고, 컴파일러가 이를 스레드 블록에 매핑한다 . 브랜드가 붙은 partition index와 bounded iterator를 통해 컴파일러는 컴파일 시점에 메모리 접근이 서로 겹치지 않음을 증명할 수 있다. 그래서 런타임 bounds check를 단순히 숨기는 것이 아니라 제거한다. 매크로로 생성된 호스트 코드(#[cutile::module])는 mutable output tensor를 서로 겹치지 않는 mutable sub-tensor로 나누고, input은 shared reference로 전달하며, 커널을 cubin으로 JIT 컴파일한다. GPU 작업이 진행 중인 동안에도 소유권은 유지된다. 더 낮은 수준의 제어가 필요할 때는 명시적인 unsafe 탈출구가 남아 있다.

이것이 단순 데모에 그치지 않는 이유는 함께 공개된 산출물 때문이다. cuTile Rust로 만든 Qwen3 추론 엔진 Grout은 100% Rust로 작성됐고, Apache-2.0 라이선스이며, huggingface/grout에 공개돼 있다 . CUDA graph decode, device-side argmax token selection, FP16 accumulation을 지원한다. 마이크로벤치마크 래퍼가 아니라 end-to-end decoder다.

저자들은 기여를 분명하게 설명한다. 공식 Rust users forum에 올라온 팀의 글에 따르면, "관용적인 Rust로 작성한 memory-safe, data-race-free GPU code가 벤더 라이브러리에 가까운 성능에 도달할 수 있다"는 것이다 . 아래에서는 그 주장이 어디까지 성립하는지 살펴본다.

Rust 소유권을 CUDA까지 가져가는 방식: partition, iterator, JIT launch

Rust's borrow checker reaches CUDA — and the cost is zero

cuTile Rust는 런타임에 확인하는 대신 컴파일 시점에 메모리 접근이 서로 겹치지 않음을 증명함으로써 Rust의 소유권 계약을 CPU→GPU 실행 경계 너머까지 가져간다. 이 메커니즘은 컴파일러가 볼 수 있는 두 가지 구성 요소, 즉 브랜드가 붙은 partition index와 bounded iterator 위에 놓여 있다. 각 커널은 고정 크기 데이터 타일 위에서 단일 스레드 의미론으로 실행되고, 컴파일러가 이를 스레드 블록에 매핑한다. 브랜드는 두 partition이 절대 alias되지 않음을 컴파일러가 검증하게 해 준다. 그래서 일반적인 런타임 bounds check는 단순히 최적화로 사라지는 것이 아니라 제거된다 . 결과적으로 안전성에 대한 판단은 커널이 실행되기 전에 전부 끝난다.

GPU 작업이 진행되는 동안 소유권을 보존하는 곳은 호스트 측이다. #[cutile::module] 매크로는 mutable output tensor를 서로 겹치지 않는 mutable sub-tensor로 나누고 input은 shared reference로 전달하는 launch code를 생성한다. GPU 관점으로 보면 writer마다 하나의 &mut을 나눠 주고, reader마다 &를 주는 셈이다 . partition은 구조상 서로 겹치지 않기 때문에 Rust의 borrow checker는 이 분할을 sound하다고 받아들이고, caller는 launch가 지속되는 동안 backing tensor의 소유권을 유지한다. 실행 시점에는 커널이 cubin으로 JIT 컴파일되므로, 같은 소스가 빌드 시점에 고정되는 대신 현재 존재하는 target GPU에 맞춰 컴파일된다.

개발자 입장에서 실제 모습은 이렇다:

  • 런타임 bounds check가 없다. 브랜드가 붙은 index와 bounded iterator가 컴파일 시점에 disjointness proof를 처리하므로, device code에는 순진한 safe abstraction에서 생길 법한 access별 guard 비용이 남지 않는다 .
  • 소유권이 경계를 넘어 유지된다. 매크로로 생성된 호스트 코드는 &/&mut sub-tensor를 전달하므로, concurrent writer 사이의 aliasing bug는 profiler에서 발견되는 것이 아니라 cargo build에서 거부된다.
  • 실행을 조합할 수 있다. 호스트 측 launch는 synchronous call, asynchronous pipeline, CUDA graph replay 전반에서 조합된다. 그래서 Grout 같은 엔진이 decode step을 graph로 capture하고 replay할 수 있다 .

이 모델은 safe surface가 모든 것을 덮는 척하지 않는다. safe API로 표현할 수 없는 경우를 위해 programmer는 unsafe 탈출구를 유지한다. 명시적인 warp primitive, 수동 shared-memory management, SIMT CUDA kernel이 직접 노출하는 더 낮은 수준의 제어가 여기에 해당한다 . 이는 Rust가 CPU에서 맺는 것과 같은 거래다. 전부 아니면 전무식의 장벽이 아니라, 확인되는 기본 경로와 unchecked control로 들어가는 분명히 표시된 문을 제공한다. tile abstraction은 CUDA의 가장 낮은 수준 표현력 일부를 컴파일러가 추론할 수 있는 기본 경로와 맞바꾸며, 정말 필요한 커널을 위해 unchecked opt-out을 남겨 둔다.

이를 평가하는 사람이라면 두 가지 설계 선택을 짚어둘 만하다. 첫째, tile마다 단일 스레드 의미론을 갖는다는 점이 borrow reasoning을 다룰 수 있게 만든다. concurrency는 programmer가 쓰는 kernel body 안이 아니라 tile이 block에 매핑되는 방식에 있다. 둘째, launch 시점의 JIT-to-cubin은 공식 Rust users forum에서 workflow의 일부로 소개됐다 . 즉 반복 작업은 별도의 device toolchain 단계가 아니라 일반적인 Rust edit-compile-run에 가깝다.

안전한 Rust CUDA GEMM: cuBLAS의 96%, 추가 비용 0

핵심 마이크로벤치마크 결과는 cuTile Rust의 안전한 커널이 측정 가능한 오버헤드 없이 벤더 라이브러리 수준의 속도로 실행된다는 점입니다. NVIDIA B200의 f16 환경에서 원소별 연산은 약 7.02 TB/s에 도달하며, 이는 최대 DRAM 대역폭의 약 91%입니다. M=N=K=8192 행렬 곱셈은 2.07 PFLOP/s를 기록했고, 논문 초록에서는 이를 cuBLAS의 약 96%로 보고합니다 . 중요한 것은 절대 수치 자체가 아니라 그 위치입니다. borrow check를 거친 경로가 raw pointer 및 cuBLAS 기준선과 맞먹기 때문에, 앞서 설명한 안전성 장치는 이 테스트들에서 런타임 비용을 만들지 않습니다 .

대역폭에 묶이는 경우에는 원소별 커널이 측정 오차 범위 안에서 cuTile Python과 일치합니다 . 이 동등성이 중요한 이유는 Rust의 `&`/`&mut` 계약과 컴파일 타임 분리성 증명이 Python 타일 DSL이 이미 치르는 비용 외에는 아무것도 더하지 않는다는 점을 보여주기 때문입니다. 생성되는 Tile IR도 같고, 메모리 트래픽도 같습니다. 다만 짚고 넘어갈 만한 주의점이 하나 있습니다. GitHub README는 GEMM 결과를 cuBLAS의 96%가 아니라 dense f16 peak의 약 92%로 설명합니다 . 이는 서로 다른 분모입니다. 하나는 하드웨어 최대 처리량이고, 다른 하나는 튜닝된 벤더 라이브러리입니다. 모순은 아니지만, 어떤 기준선에 대한 비율인지 확인해야 한다는 뜻입니다.

더 직접적인 증거는 GEMM 비교 안에 있습니다. 안전한 mapped 커널은 raw pointer 변형과 같은 성능을 보이고, 안전한 persistent GEMM은 대응하는 저수준 Tile IR 버전과 약 0.3% 이내의 차이에 머뭅니다 . 다시 말해 여기서는 `unsafe` raw pointer로 내려가도 얻는 것이 사실상 없습니다. 이는 borrow check나 bounds check가 적용된 코드는 오케스트레이션에는 괜찮지만 내부 루프에는 너무 느리다는 통념을 약화합니다. 적어도 이 벤치마크가 다루는 타일 매핑 패턴에서는 그렇습니다.

벤치마크(B200, f16)안전한 cuTile Rust기준선 / 참조
원소별 처리량≈7.02 TB/s(최대 DRAM BW의 ~91%)측정 오차 범위 안에서 cuTile Python과 일치
GEMM, M=N=K=81922.07 PFLOP/scuBLAS의 ~96%(초록); dense f16 peak의 ~92%(README)
안전한 mapped GEMMraw-pointer 변형과 일치측정 가능한 차이 없음
안전한 persistent GEMM저수준 Tile IR 대비 ~0.3% 이내수작업 튜닝 Tile IR 커널

Source: "Fearless Concurrency on the GPU," arXiv:2606.15991 , and the cutile-rs repository .

개발자가 가져갈 결론은 분명합니다. 안전성 추상화는 컴파일 과정에서 사라집니다. branded partition index, bounded iterator, 서로 겹치지 않는 mutable subtensor 분할은 모두 컴파일 타임에 해소되므로, 최종 device code는 직접 손으로 썼을 코드와 같습니다. 단지 증명 없이 작성했을 때와 다를 뿐입니다. GPU 시스템 프로그래머에게 이는 트레이드오프의 틀을 바꿉니다. 적어도 이 마이크로벤치마크에서는 데이터 레이스와 out-of-bounds 접근을 막는 컴파일 타임 보장이 처리량으로 대가를 치르는 기능이 아니게 됩니다. 남는 질문은 이 결과가 여기서 측정한 타일 매핑 GEMM과 원소별 형태를 넘어 어디까지 일반화될 수 있느냐입니다. 저자들도 이 경계를 명시하고 있으며, 다음 섹션들이 바로 그 지점을 다룹니다.

B200의 Grout: Qwen3-32B 디코드 80 Tok/s

Rust's borrow checker reaches CUDA — and the cost is zero

저자들이 cuTile Rust 위에 구축한 Qwen3 추론 엔진 Grout는 배치 1에서 Qwen3-32B를 실행하는 B200 기준 생성 토큰 80.1개/s에 도달한다. 이는 HBM roofline 추정치의 약 66.7%다. 또한 Qwen3-4B를 실행하는 RTX 5090에서는 154.7 tok/s로, roofline의 약 74.7%에 해당한다 . 같은 Section 5.3 스윕에서 생성 길이 tg=8192일 때, B200/Qwen3-32B 조건에서 vLLM 0.18.0은 77.5 tok/s, SGLang 0.5.9는 76.5 tok/s를 기록했다 . 고성능 서빙의 기준선을 정의하는 두 엔진과 단일 스트림 디코드에서 대등한 수준을 100% Rust 스택으로 달성한 것이다 .

빠른 답변: B200에서 Qwen3-32B를 배치 1, f16, prefix caching 비활성화 조건으로 실행하면 Grout는 80.1 tokens/s로 디코드한다. vLLM 0.18.0은 77.5, SGLang 0.5.9는 76.5다. 각 셀당 10회 반복 측정하고 중앙값과 IQR 음영으로 표시한 결과이며, 시스템 수준 지연 시간에서 대등한 수준이다.

숫자만큼 중요한 것이 설정이다. 모든 실행은 f16, 배치 1, prefix caching 비활성화 조건이었다. vLLM은 CUDA graphs를 켰고, SGLang은 RadixAttention을 껐다. 따라서 이 비교는 해당 시스템들이 최적화해 온 고동시성 처리량이 아니라 단일 스트림 디코드 지연 시간을 분리해서 본다 . 출처도 고정돼 있다. cuTile Rust 0.2.0, Grout commit 4631fb01, vLLM 0.18.0, SGLang 0.5.9이며, RTX 5090은 짧은 크기에서 10회 반복, 2048/8192에서 3회 반복, B200은 셀당 10회 반복을 사용했다 .

엔진스택B200 / Qwen3-32B 디코드 (tg=8192)
Grout100% Rust (cuTile Rust 0.2.0)80.1 tok/s (roofline의 66.7%)
vLLM 0.18.0Python + CUDA C++, CUDA graphs 켬77.5 tok/s
SGLang 0.5.9Python + CUDA C++, RadixAttention 끔76.5 tok/s

정직하게 봐야 할 단서가 하나 있다. Grout의 모델 GEMM은 여전히 cuBLAS로 fallback한다 . 따라서 이 헤드라인은 순수 Rust 대 C++ 커널 대결이 아니다. 안전한 Rust 경로가 끝까지 소유하는 것은 엔진이다. CUDA-graph 디코드, device-side argmax와 토큰 선택, FP16 accumulation, Qwen3 safetensors 위의 greedy 또는 sampled generation이 여기에 해당한다 . 반면 가장 조밀한 행렬곱은 NVIDIA 라이브러리에 위임한다. 결과적으로 이는 시스템 수준의 디코드 속도 주장이다. borrow check를 받는 Rust 추론 루프가 cuBLAS를 오케스트레이션해 성숙한 서빙 스택과 배치 1에서 대등한 수준에 도달했고, 이는 실무자들이 RTX 5090 같은 소비자용 카드에서 점점 더 많이 벤치마크하는 로컬 LLM 지연 시간 목표이기도 하다(video: Alex Ziskind).

"Grout is a minimal testbed, not a general-purpose serving-stack replacement; concurrent-batching throughput is left to future work," — Elibol, Roesch, Gelado, Garland and Buehler, "Fearless Concurrency on the GPU" (source: arXiv:2606.15991).

핵심은 바로 이 프레이밍이다. 저장소에는 커밋이 많지 않고 태그 릴리스도 없다. 다른 곳에 공개된 대표 배치 1 수치인 RTX 5090의 Qwen3-4B 171 tok/s, B200의 Qwen3-32B 82 tok/s 역시 멀티 테넌트 서버 처리량이 아니라 단일 스트림 지연 시간을 설명한다. 좁게 읽으면 증거는 강하다. 안전한 Rust는 이미 경쟁력 있는 디코드 루프를 구동할 수 있다. 넓게 읽으면 아직 입증되지 않았고, 저자들도 그렇게 말한다.

저자들은 주장의 범위를 이렇게 좁혔다

동등성 주장은 의도적으로 좁다. Grout가 vLLM 및 SGLang과 맞먹는 것은 배치 1, 단일 스트림 디코드에서뿐이다. 이 엔진들이 중심에 두고 설계된 멀티 테넌트 동시성까지 주장하는 것은 아니다. Section 5.3 스윕은 B200에서 Qwen3-32B를 실행할 때 Grout 80.1 tok/s, vLLM 0.18.0 77.5 tok/s, SGLang 0.5.9 76.5 tok/s를 보고한다. 모두 f16, 배치 1, prefix caching 비활성화 조건이다 . 저자들은 Grout가 범용 서빙 스택 대체물이 아니며, PagedAttention, continuous batching, RadixAttention이 제값을 하는 고동시성 배치 처리량 영역은 별도의 향후 과제라고 명확히 말한다 . 결과는 단일 스트림 지연 시간 동등성이다. 서버 처리량 동등성은 주장하지 않는다.

안전성 모델 역시 표현 가능한 영역을 줄인다. 논문의 한계 섹션은 cuTile Rust가 SIMT CUDA와 비교해 낮은 수준 제어 표면을 줄여서 노출한다고 설명한다. 명시적 warp primitive와 수동 shared-memory 관리는 safe API에서 완전히 표현되지 않으며, 프로그래머가 그런 제어가 필요할 때는 unsafe escape hatch로 fallback한다 . 일부 크기에서는 GEMM에도 아직 빈틈이 있고, Grout의 모델 GEMM은 전부 cuTile 커널에서 실행되는 대신 cuBLAS로 fallback한다 .

저자들의 설명 자체로도 엔지니어링 성숙도는 초기 단계다. 현재 결과가 일반화될 수 있는 범위에는 몇 가지 제약이 있다.

  • 범위는 NVIDIA 전용이다. 이 파이프라인은 CUDA Tile IR을 대상으로 하며 compute capability sm_80 이상, 즉 A100, H100, B200을 요구한다. 다른 벤더로의 이식성 이야기는 없다 .
  • 지원 모델 폭이 좁다. Grout는 safetensors로 저장된 Qwen3 디렉터리만 지원하며, speculative decoding과 multi-GPU 실행은 없다 .
  • 테스트베드는 최소 구성이다. 공개 Grout repository에는 커밋이 많지 않고, 태그 릴리스도 없으며, 벤치마크 수치도 저장소에 커밋돼 있지 않다. 핵심 수치는 코드가 아니라 논문에 있다 .

vLLM과 SGLang의 실제 기능 범위, 즉 continuous batching, prefill-decode disaggregation, 그리고 SGLang의 400,000개 이상 GPU에 걸친 배포 주장 과 비교하면, 차이는 최고 단일 스트림 속도가 아니라 폭에 있다. 이것은 저자들 자신의 프레이밍이기도 하다. 그래서 CUDA 위의 borrow checker라는 이야기가 신뢰성을 얻는다. 주장이 사실일 만큼 작고, 1차 출처가 그 경계를 직접 긋고 있기 때문이다.

cuTile Rust 0.2.0: Apache 2.0, sm_80+ 그리고 아직 비어 있는 영역

Rust's borrow checker reaches CUDA — and the cost is zero

cuTile Rust 0.2.0은 초기 단계의 NVIDIA 전용 툴체인으로, 하드웨어와 소프트웨어 하한선이 분명하다. NVIDIA GPU 중 compute capability sm_80 이상, 즉 A100, H100, B200이 필요하고, CUDA 13.3 및 Rust 1.89+가 요구되며, Ubuntu 24.04에서 테스트됐다 . 버전 0.2.0은 2026년 6월 16일에 공개됐고, 저장소에는 초기 단계이며 API 변경이 예상된다고 명시돼 있다. 지금 도입하는 팀은 계속 움직이는 기반 위에 쌓는 셈이다 .

라이선스는 나뉘어 있다. NVlabs/cutile-rs의 Rust 크레이트는 Apache 2.0이지만, 함께 제공되는 cuda-bindings는 NVIDIA Software License를 따른다. 의존성 라이선스 검토가 엄격한 팀에는 중요한 차이다 . Qwen3 추론 테스트베드인 Grout은 별도로 huggingface/grout에서 Apache 2.0으로 공개돼 있으며, 100% Rust로 작성됐다 .

재현성 측면에서 저자들은 논문 벤치마크를 다시 실행하는 데 필요한 아티팩트를 공개하되, 의도적으로 선을 그었다. 저장소에는 벤치마크 코드와 출처 정보, 즉 cuTile Rust 0.2.0, 고정된 Grout 커밋, vLLM 0.18.0, SGLang 0.5.9가 포함돼 있다. 반면 원시 프로파일링 트레이스, 모델 가중치, 빌드 아티팩트, 대규모 생성 출력은 의도적으로 제외됐다 . 덕분에 저장소는 작게 유지되지만, 완전한 비트 단위 재현을 하려면 자체 가중치와 프로파일링 환경을 준비해야 한다.

알려진 한계도 숨기지 않고 분명히 적혀 있다. SIMT CUDA와 비교하면 cuTile Rust가 제공하는 저수준 제어 범위는 더 좁다. 명시적 warp primitive가 없고, 공유 메모리를 수동으로 관리할 수도 없으며, 일부 크기에서는 GEMM 격차가 남아 있고 Grout의 모델 GEMM은 cuBLAS로 폴백한다 . 텐서 API는 아직 초기 단계이고, 일부 raw pointer 사용이 남아 있으며, Tile IR과 sm_80+ 하한선 자체가 NVIDIA 특화이기 때문에 범위도 구조적으로 NVIDIA 전용이다 .

읽어볼 만한 신호가 하나 있다. 이 작업은 arXiv뿐 아니라 공식 Rust 사용자 포럼에도 발표됐고, 저자들은 이를 Rust로 작성하는 안전한 GPU 커널이라고 설명했다 . ML 인프라 채널에만 올린 것이 아니라 users.rust-lang.org에 게시했다는 점은, 추론 엔진 팀만이 아니라 더 넓은 Rust 시스템 커뮤니티와 소통하려는 의도를 보여준다. 언어 수준의 피드백을 받아들일 만큼 아직 이른 프로젝트라는 위치 설정에도 맞다.

Rust ML 프레임워크 작성자에게 주는 의미

Rust ML 프레임워크 작성자에게 cuTile Rust가 주는 실용적 신호는, 이제 Rust가 호스트 측 텐서 API 계층 아래에서도 가능하다는 점이다. C++ 커널을 감싸는 오케스트레이션용 접착 코드에 그치지 않고, CUDA 코드 자체에도 Rust를 쓸 수 있다는 뜻이다. 논문은 안전하고 borrow check를 거치는 GPU 커널이 8192³ GEMM에서 cuBLAS의 약 96%에 도달하고, element-wise 작업에서 최대 DRAM 대역폭의 약 91%에 이른다고 보여준다 . 이는 GPU에서 컴파일 타임 안전성을 얻으려면 처리량을 희생해야 한다는 오랜 가정을 약화시키며, 광범위한 unsafe나 손으로 작성한 CUDA C++ 없이 커스텀 fused kernel을 작성할 길을 연다.

주요 대상은 커널 수준에서 컴파일 타임 race 제거를 원하는 GPU 시스템 프로그래머다. cuTile Rust는 Rust의 &/&mut 계약을 launch 경계 너머로 확장한다. 그래서 CPU Rust를 안전하게 만드는 disjoint-access 보장이 이제 thread-block에 매핑된 tile에도 적용된다 . Rust 추론 스택을 유지하는 팀 입장에서는, 커스텀 attention이나 normalization 커널에도 주변 호스트 코드와 같은 ownership 규율을 적용할 수 있다는 뜻이다.

이 이야기에서 솔직한 부분은 cuBLAS 폴백이다. Grout은 여전히 모델 GEMM을 cuTile Rust로 끝까지 실행하지 않고 cuBLAS에 맡긴다 . 바로 이 지점이 안전한 Rust 경로가 이미 프로덕션 수준에 가까운 곳과 아직 벤더 라이브러리에 기대는 곳을 정확히 표시한다. 이런 솔직함은 깔끔한 동등 성능 헤드라인보다 더 중요하다.

저자들이 논문에서 말했듯이, 기여는 제한적이지만 구체적이다. NVIDIA와 Hugging Face의 Melih Elibol 및 공동 저자들은 벤더 라이브러리에 가까운 성능에 도달하는 "memory-safe, data-race-free GPU code written in idiomatic Rust"를 제시했다 (source: arXiv:2606.15991) .

지켜볼 점은 두 가지다. 첫째, 0.2.0 이후 API 안정화가 뒤따르는지다. 이 프로젝트는 초기 단계이며 변경이 예상된다고 명시돼 있으므로 , 프레임워크 작성자는 버전을 고정하고 변화를 감수해야 한다. 둘째, NVIDIA 밖으로 범위가 확장되는지다. 현재 이 작업은 Tile IR에 묶여 있고 sm_80 이상을 요구한다 . AMD/ROCm이나 Apple Metal 타깃이 생기면 이식성 계산이 달라질 것이다. 구체적인 결론은 이렇다. Rust ML 인프라를 만든다면 cuTile Rust로 프로토타입 커널을 만들어볼 가치는 지금도 있다. 다만 0.2.0은 안정 의존성이 아니라 연구 프리뷰로 다뤄야 한다.

자주 묻는 질문

cuTile Rust를 쓰려면 어떤 하드웨어가 필요한가요?

cuTile Rust는 compute capability sm_80 이상인 NVIDIA GPU, 즉 A100, H100, B200에서만 실행되며 CUDA 13.3과 Rust 1.89+가 필요합니다. 테스트는 Ubuntu 24.04에서 진행되었습니다 . 현재 AMD/ROCm이나 Apple Silicon 경로는 없습니다. 모델이 NVIDIA의 CUDA Tile IR로 낮춰지기 때문에, 당분간 범위는 NVIDIA 전용입니다 . 지원 매트릭스는 좁고 버전에 고정되어 있다고 보는 편이 맞습니다.

CUDA 코드에 Rust borrow-checking을 더하면 런타임 오버헤드가 생기나요?

논문의 마이크로벤치마크 기준으로는 그렇지 않습니다. 안전성 추상화는 컴파일 과정에서 사라집니다. GEMM(M=N=K=8192, NVIDIA B200, f16)에서 안전한 mapped kernel은 raw pointer 변형과 같은 성능을 보였고, 안전한 persistent GEMM은 대응되는 저수준 Tile IR 버전과 대략 0.3% 이내 차이에 들어왔습니다 . Element-wise 연산은 약 7.02 TB/s에 도달해 피크 DRAM bandwidth의 약 91% 수준이었고, 측정 오차 범위 안에서 cuTile Python과 비슷했습니다 . borrow-check 계약은 런타임이 아니라 컴파일 타임에 강제됩니다.

Grout은 프로덕션에서 vLLM이나 SGLang을 대체할 준비가 됐나요?

아닙니다. 저자들은 Grout을 범용 serving stack이 아니라 cuTile Rust의 end-to-end 동작을 보여주는 실험용 testbed라고 명시합니다 . Grout은 batch 1과 Qwen3만 지원하고, multi-GPU와 concurrent batching은 없으며, 공개 repo도 최소 구성입니다. commit이 적고, tagged release가 없으며, benchmark 수치도 commit되어 있지 않습니다 . 프로덕션 serving에는 vLLM과 SGLang이 목표로 삼는 높은 동시성 throughput이 필요하지만, Grout은 아직 그 영역을 다루지 않습니다.

batch 1에서 vLLM, SGLang과 비교한 결과는 어떻게 봐야 하나요?

단일 스트림 latency가 비슷하다는 의미로만 읽어야 합니다. 조건을 맞춘 상태(B200, Qwen3-32B, f16, batch 1, prefix caching disabled, tg=8192)에서 Grout은 80.1 tok/s를 기록했고, vLLM은 77.5 tok/s, SGLang은 76.5 tok/s였습니다 . 이는 장난감 baseline이 아니라 검증된 엔진과 batch 1 decode parity를 확인한 결과입니다. vLLM의 PagedAttention과 SGLang의 RadixAttention이 최적화하는 multi-tenant, high-concurrency throughput은 여기서 테스트되지 않았고, 저자들도 future work로 표시했습니다 .

cuTile Rust와 Grout에는 어떤 라이선스가 적용되나요?

cuTile Rust는 dual license입니다. Rust crate(cutile-rs, 2026년 6월 16일 기준 version 0.2.0)는 Apache 2.0이고, cuda-bindings는 NVIDIA Software License가 적용됩니다 . Grout(huggingface/grout)은 전체가 Apache 2.0이며 100% Rust로 작성되어 있습니다 . 둘 중 하나를 vendoring한다면 license boundary가 나뉘어 있다는 점과 0.2.0이 초기 단계라 API breakage가 예상된다는 점을 확인해야 합니다.