테마 전환

GUIDE는 시작하기 전에 이 서버가 어떻게 생겼는지 파악하는 데 필요한 네 가지 추상화를 정리해 둡니다. 이 글에서는 이를 spec.md(바인딩 설계 문서)와 PLUGIN.md의 내용을 보태 다시 풀어 씁니다. 이해해 두면 뒤의 사용·운영 글에서 등장하는 플래그들이 왜 그런 모양인지 금방 납득됩니다.
모델 = 체크포인트 또는 .rad 컨테이너
첫 번째 추상화입니다. radiance에서 모델은 있는 그대로 서빙되는 체크포인트이거나 .rad 컨테이너입니다.
가중치가 bf16, f16, f32, 블록 스케일 fp8, Quark MXFP4처럼 서버가 읽을 수 있는 정밀도인 체크포인트는 디렉터리 그대로 서빙됩니다. 반대로 양자화가 필요한 것은 rad-convert가 한 번 변환해 컨테이너로 만듭니다. 컨테이너에는 다음이 전부 들어갑니다.
- 각 가중치를 인코딩의 평면들(부호, 스케일, 영점, 회전)로 규격화된 배열에 담아 놓은 것
- 토크나이저와 채팅 템플릿
- 메타데이터와 변환에 쓴 레시피
- 있으면 초안 헤더(drafter)
눈여겨볼 점은 컨테이너가 커널 라이브러리를 지정하지 않는다는 것입니다. 커널 라이브러리는 로드 시점에 이 평면들을 자기 레이아웃으로 재배열합니다. 그래서 커널 라이브러리를 새 버전이나 다른 카드로 바꿔도 컨테이너를 다시 변환할 필요가 없습니다. 가중치 저장 형식과 실행 커널이 분리되어 있다는 뜻입니다.
커널은 플러그인이고, 순서가 중요하다
모든 연산(op)은 순서가 있는 커널 라이브러리 목록에 대해 해석(resolve)되고, 처음 일치하는 커널이 이깁니다. --kernels mylib,libref처럼 라이브러리를 순서대로 지정할 수 있고, 여기서 빠진 라이브러리는 아예 로드되지 않습니다. 목록을 생략하면 찾은 모든 라이브러리가 로드되고, 자기 자신을 참고 구현(reference)이라 선언한 라이브러리는 맨 뒤에 놓입니다.
radiance에 동봉된 커널 라이브러리는 셋입니다.
| 라이브러리 | 역할 |
|---|---|
libr4d | AMD RDNA4(gfx12xx) 장치 라이브러리. 페이지드·밀집 어텐션, 게이트된 delta net, P2P 또는 호스트 메모리 우편함 기반 all-reduce, skinny·타일 양자화 GEMM, rotate-and-quantise 퓨전 등 |
libref | 모든 연산을 순수하고 일반적인 방식으로 구현한 라이브러리. 최후의 폴백인 동시에 rad-kbench가 다른 커널을 검증하는 기준(oracle) |
libavx | 호스트(x86 SIMD) 라이브러리. 같은 연산 어휘를 CPU 기능에 따라 로드 시 디스패치. 호스트에 놓인 모든 op(예: n-gram embedding gather)를 담당 |
자기 라이브러리가 구성 중인 카드를 커버하지 못하면 그 라이브러리는 빌드에서 빠지고 트리는 계속 빌드·실행됩니다. 카드 지원이 곧 플러그인 하나라는 뜻입니다.
아키텍처도 플러그인이다
arch/<id>/ 아래의 아키텍처 플러그인은 모델 families의 그래프를 선언합니다 — 가중치, 버퍼, 그리고 순서대로 발행하는 op들입니다. 언어 모델뿐 아니라 이미지·비디오·오디오 모델도 각각 플러그인으로 들어 있습니다.
| 모델 | 아키텍처 플러그인 |
|---|---|
| MiniCPM5, Llama 3 등 LLaMA 형태 디코더 | llama_fp8, llama_dense_fp8 |
| Qwen3.5/3.6/3.8 dense (0.8B~27B) | qwen35_bf16, qwen35_fp8, qwen35_w8a8 |
| Qwen3.8-Flash-Next(512 expert 하이브리드) | qwen4exp_fp8 |
| Gemma 4 dense·MoE | gemma4, gemma4_bf16 |
| 이미지 생성 | qwenimage21, krea2, anima, flux3 |
| 비디오 생성 | minimaxh3, ltx2 |
| 음성·음악 | breeze, fishomni, minimaxmusic3, qwen3asr_bf16 |
| 임베딩 | embgemma2, nomicbert, nemotron35_embed |
새 모델 families을 추가하는 일은 곧 아키텍처 플러그인을 추가하는 일입니다. 엔진 코어를 고치는 일이 아니라 arch/에 플러그인을 하나 넣는 일입니다.
양자화기도 플러그인이다
세 번째 종류의 플러그인은 양자화기(quantiser) 입니다. 체크포인트의 가중치를 인코딩의 평면으로 바꾸는 역할을 하며, rad-convert가 레시피에 따라 호출합니다. 세 종류 플러그인 모두 radiance의 어떤 코드에도 링크되지 않은 공유 오브젝트(.so)이고, 설치된 abi/ 헤더만으로 컴파일됩니다. 인터페이스는 다음 절에 적듯exports 몇 개뿐입니다. 이 덕분에 radiance를 빌드하지 않은 서드파티도 플러그인을 배포할 수 있고, ctest -L oot은 동봉 플러그인을 저장소 밖에서 설치된 radiance에 대해 다시 빌드해 같은 결과가 나오는지 검사합니다.
libref 폴백은 치명적이다
네 번째로 GUIDE가 강조하는 규칙 — 어떤 op가 libref로 해석되면 엔진은 시작을 거부하고 해당 op 이름을 댑니다. libref로 서빙하면 몇 자릿수(order of magnitude)나 느린데 출력으로는 그게 안 드러나기 때문입니다. libref로 남은 목록은 곧 "새 커널 라이브러리가 아직 구현해야 할 일"입니다. 브링업 중에만 --debug-accept-reference-kernels로 예외를 둘 수 있습니다.
모든 풀은 명시적으로 예산을 잡는다
radiance에는 프로파일링 패스도, 사용률 퍼센트도 없습니다. 모든 메모리 풀은 운영자가 명시적으로 예산을 정합니다. KV 블록과 상주 가중치 사이의 균형은 워크로드에 달려 있어서 운영자가 결정할 몫이라는 판단입니다. 엔진이 알아서 다시 최적화한 분할은 벤치마크를 재현 불가능하게 만듭니다. 그래서 카드 분할 계획(--gpu-headroom-mib, --host-pool-mib 등)이 전부 명시적 플래그로 노출되고, 부팅 로그가 모든 항을 인쇄합니다. 이 원칙이 실제 플래그로 어떻게 나타나는지는 메모리 예산과 롱 컨텍스트에서 다룹니다.
왜 이렇게 만들었나
네 가지 추상화를 관통하는 원칙은 분리와 재현 가능성입니다.
- 저장 형식(컨테이너)과 실행 커널(라이브러리)이 분리되어 커널을 바꿔도 재변환이 없습니다.
- 모델 families·하드웨어·양자화가 전부 플러그인이라 엔진 코어를 포크하지 않고 확장합니다.
- 메모리 분할을 자동 최적화하지 않아 벤치마크가 재현됩니다.
- 참고 구현(libref)을 검증 기준이자 "미완 작업 목록"으로 명시해 두었습니다.
이 원칙은 뒤의 글에서 반복해서 등장합니다. 카드를 준비할 때, 모델을 변환할 때, 운영 지표를 읽을 때마다 이 네 추상화를 떠올리면 문서 전체가 훨씬 읽기 쉬워집니다.