주요 콘텐츠로 건너뛰기
AI 튜토리얼

호스트 RAM 오프로딩으로 단일 24GB RTX 3090에서 GLM-5.3-Flash 실행

이 튜토리얼에서는 glm53-flash-offload가 고정 호스트 메모리, 탄력적인 GPU 전문가 캐시, 제로 카피 PCIe 액세스, 선택적 AVX2 CPU 연산을 결합해 단일 24GB NVIDIA GPU에서 GLM-5.3-Flash를 서비스하는 방법을 설명합니다. Docker 이미지를 설치하고, 빠른 모드 또는 정확한 모드를 선택하며, API를 호출하고, 성능을 검증하고, 배포를 조정하는 과정을 다룹니다.

호스트 RAM 오프로딩으로 단일 24GB RTX 3090에서 GLM-5.3-Flash 실행

개요

glm53-flash-offload는 단일 24 GB NVIDIA GPU와 호스트 DDR4 메모리에서 125.3 GB 용량의 EXL3 3.05-bpw 빌드 GLM-5.3-Flash를 제공합니다. OpenAI 호환 HTTP API를 노출하며, 라우팅된 혼합 전문가 모델의 가중치는 주로 고정 시스템 RAM에 유지합니다.

이 프로젝트는 기본 exllamav3 1.5.1에 대한 얇은 몽키 패치 모음이며, 여러 개의 소규모 커스텀 커널이 추가로 포함되어 있습니다. exllamav3 소스 코드를 수정할 필요가 없습니다. 문서화된 구성은 PCIe 4.0 x16으로 연결된 RTX 3090과 AMD EPYC 7443P 시스템에서 측정되었습니다.

핵심 아이디어는 자주 사용되는 전문가를 탄력적인 GPU 캐시에 유지하는 것입니다. 캐시에서 누락된 전문가는 PCIe를 통해 고정 호스트 메모리에서 직접 읽을 수 있습니다. 빠른 모드에서는 디코드 중 가장 오래 사용되지 않은 캐시 누락을 AVX2 CPU 워커에서 대신 처리할 수 있습니다.

주요 기능

  • 단일 GPU 배포: 24 GB RTX 3090급 GPU 하나로 GLM-5.3-Flash를 제공합니다.
  • OpenAI 호환 API: 채팅 완성, 텍스트 완성, 모델 검색, 스트리밍, 추론 콘텐츠 및 OpenAI 스타일의 도구 호출을 지원합니다.
  • 고정 제로 카피 저장소: 라우팅된 모든 전문가는 고정 호스트 RAM에 보관되며 CUDA 통합 가상 주소 지정을 통해 액세스할 수 있습니다.
  • 탄력적 GPU 전문가 캐시: 자주 사용되는 전문가는 사용 가능한 VRAM을 차지하며, 긴 프리필 활성화 및 스테이징 버퍼를 위해 캐시 공간을 일시적으로 반환할 수 있습니다.
  • 프리필 스테이징: 캐시되지 않은 전문가는 한 레이어 앞서 복사되어 PCIe 전송과 계산이 겹쳐 실행될 수 있습니다.
  • 선택적 CPU 계층: 빠른 모드에서는 선택된 콜드 디코드 캐시 누락을 AVX2 CPU 커널에 할당합니다.
  • 배치 디코드: 문서화된 -ambs 4 구성으로 최대 네 개의 스트림을 함께 디코드할 수 있습니다.
  • 재현 가능한 구성: 모델 리비전, 컨테이너 다이제스트, exllamav3 버전, Triton 선택 사항, 벤치마크 및 참조 품질 패널이 고정되어 있습니다.

빠른 모드와 정확 모드 중 선택

서버는 GLM53_MODE 환경 변수를 통해 두 가지 작동 모드를 제공합니다.

빠른 모드

fast가 기본값입니다. GPU 전문가 캐시, 제로 카피 캐시 누락, 선택된 콜드 디코드 캐시 누락에 대한 AVX2 CPU 처리, 배치 디코드 및 융합 디코드 커널을 결합합니다. 측정된 호스트에서는 약 218 GiB, 즉 234 GB의 호스트 RAM을 사용했습니다.

공개된 테스트에서 디코드 스트림 하나는 초당 약 28.15토큰, 스트림 두 개는 초당 총 31.57토큰, 스트림 네 개는 초당 총 33.98토큰을 기록했습니다. 현재 다이제스트의 이미지 스모크 테스트에서는 각각 초당 총 28.88, 31.27, 35.00토큰을 측정했습니다.

품질 경고: 프리필은 정확하지만 빠른 모드의 디코드는 기본 exllamav3와 비트 단위로 동일하지 않습니다. 쌍별 디코드 검사에서 평균 KL 0.0053, top-1 일치율 0.977이 보고되었습니다. 출력 동등성이 필요한 경우 정확 모드를 사용하세요.

정확 모드

exact는 CPU 계층과 빠른 모드 전용 디코드 커널을 비활성화합니다. GPU 전문가 캐시와 제로 카피 호스트 메모리 캐시 누락은 유지합니다. 참조 패널에서는 top-1 일치율 1.0000과 KL 0을 기록했으며, 호스트 메모리 사용량은 약 111 GiB, 즉 119 GB였습니다.

정확 모드는 더 느리지만 RAM을 훨씬 적게 사용합니다. 측정된 단일 스트림 디코드 속도는 더 짧은 테스트 컨텍스트에서 초당 12.57토큰이었으며, 기본 exllamav3가 맞지 않는 전문가를 CPU 워커에 배치했을 때의 초당 약 7.5~8.4토큰과 비교됩니다.

하드웨어 및 소프트웨어 요구 사항

GPU 및 드라이버

  • VRAM 24 GB의 NVIDIA GPU 한 대.
  • 측정 대상은 RTX 3090 또는 A5000과 같은 sm_86 GPU입니다.
  • 포함된 sm_86 바이너리는 RTX 4090을 포함한 sm_89에서도 실행되지만, 해당 구성은 측정되지 않았습니다.
  • 이미지가 CUDA 13.0.3을 사용하므로 CUDA 13.0을 지원하는 NVIDIA 드라이버가 필요합니다.
  • PCIe 4.0 x16을 권장합니다. 측정된 링크에서 캐시 누락은 약 25 GB/s를 사용합니다.

호스트 메모리

  • 빠른 모드: 다른 작업이 거의 실행되지 않을 때 총 256 GiB 메모리가 최소 기준이며, 320 GB 이상을 권장합니다. Docker 메모리 제한을 사용하는 경우 최소 230g을 허용하세요.
  • 정확 모드: 128 GiB가 최소 기준이며, 160 GB 이상을 권장합니다.

CPU 및 저장 장치

  • 빠른 모드에는 AVX2, FMA 및 F16C를 지원하는 x86-64 CPU가 필요합니다.
  • 측정된 빠른 모드 성능을 위해 물리 코어 약 24개와 8채널 DDR4 이상을 권장합니다.
  • 체크포인트는 디스크에서 약 117 GiB, 즉 125.3 GB를 차지합니다.
  • 모델 로딩 시간을 줄이려면 NVMe 저장 장치를 권장합니다.
  • 문서화된 설정에는 Docker, NVIDIA Container Toolkit 및 Hugging Face CLI가 필요합니다.

Docker로 서버 설치 및 시작

1단계: 체크포인트 다운로드

고정된 3.05-bpw 체크포인트를 로컬 디렉터리에 다운로드합니다.

hf download turboderp/GLM-5.3-Flash-exl3 \
  --revision 3.05bpw \
  --local-dir /data/GLM-5.3-Flash-exl3-3.05bpw

대신 /models에 빈 디렉터리를 마운트할 수도 있습니다. config.json이 없으면 컨테이너가 구성된 체크포인트를 해당 디렉터리에 다운로드합니다.

2단계: 빠른 모드 시작

다음 명령은 GPU 0에서 서버를 시작하고 포트 30000으로 공개합니다. 스트리밍 전달 수정 사항이 포함된 이미지 다이제스트를 사용합니다.

docker run -d \
  --name glm53 \
  --gpus '"device=0"' \
  --ulimit memlock=-1 \
  --shm-size 16g \
  -p 30000:30000 \
  -v /data/GLM-5.3-Flash-exl3-3.05bpw:/models \
  ghcr.io/0xsero/glm53-flash-offload@sha256:bb633b0bcb85573ad40b6c408af5e1036ae062c593e42479f4e4d2ab521e551d

서버가 호스트 메모리를 대량으로 고정하므로 --ulimit memlock=-1 설정을 권장합니다. 게시된 이미지에서는 측정에 사용한 드라이버에서 이 설정 없이도 로드되었지만, 모든 호스트에서 동일하게 동작한다고 가정해서는 안 됩니다.

3단계: 시작 과정 확인

docker logs -f glm53

loaded in ... s가 포함된 메시지가 나타날 때까지 기다립니다. 문서에 기록된 시스템에서는 캐시와 호스트 상태에 따라 시작에 대략 2~3분이 걸립니다.

4단계: 상태 확인

curl -s http://localhost:30000/health

정확 모드 실행

출력 일치도를 우선하고 호스트 메모리 사용량을 줄이려면 -e GLM53_MODE=exact를 추가합니다.

docker run -d \
  --name glm53-exact \
  --gpus '"device=0"' \
  --ulimit memlock=-1 \
  --shm-size 16g \
  -p 30000:30000 \
  -e GLM53_MODE=exact \
  -v /data/GLM-5.3-Flash-exl3-3.05bpw:/models \
  ghcr.io/0xsero/glm53-flash-offload@sha256:bb633b0bcb85573ad40b6c408af5e1036ae062c593e42479f4e4d2ab521e551d

빠른 모드와 정확 모드 예제를 같은 포트에서 동시에 실행하지 마세요. 모드를 전환하기 전에 첫 번째 컨테이너를 중지하고 삭제합니다.

docker rm -f glm53

기본 API 사용법

채팅 완성 요청 보내기

curl -s http://localhost:30000/v1/chat/completions \
  -H 'content-type: application/json' \
  -d '{"model":"glm-5.3-flash","messages":[{"role":"user","content":"Explain zero-copy model offloading."}],"max_tokens":512}'

기본으로 제공되는 모델 이름은 glm-5.3-flash입니다. 별도로 설정하지 않으면 max_tokens는 작은 고정값으로 제한되지 않고 남은 컨텍스트에 맞춰 기본 설정됩니다.

사고 기능 비활성화

GLM의 추론 결과는 reasoning_content에 반환됩니다. 요청에서 사고 기능을 비활성화하려면 채팅 템플릿 옵션을 전달합니다.

curl -s http://localhost:30000/v1/chat/completions \
  -H 'content-type: application/json' \
  -d '{"model":"glm-5.3-flash","messages":[{"role":"user","content":"Reply with one sentence."}],"chat_template_kwargs":{"enable_thinking":false},"max_tokens":128}'

응답 스트리밍

curl -N http://localhost:30000/v1/chat/completions \
  -H 'content-type: application/json' \
  -d '{"model":"glm-5.3-flash","messages":[{"role":"user","content":"Write a short explanation of mixture-of-experts models."}],"stream":true,"max_tokens":512}'

위에 표시된 고정 bb633b0b... 다이제스트를 사용하세요. 이전 1159044a... 이미지는 전체 속도로 생성했지만, 끝부분에서 대기 중인 이벤트를 한꺼번에 플러시하기 전까지 스트리밍 이벤트를 약 절반 속도로 전달했습니다.

사용 가능한 모델 목록 확인

curl -s http://localhost:30000/v1/models

런타임 통계 확인

curl -s http://localhost:30000/stats

통계 엔드포인트에는 전문가 캐시 적중 정보와 CPU 계층 카운터가 포함됩니다. 추가 엔드포인트로 /v1/completions, /server_info, SGLang 형태의 /generate 및 /tokenize 경로가 있습니다.

이 배포는 텍스트 전용입니다. 체크포인트의 비전 타워는 로드되지 않습니다.

OpenAI 스타일 도구 사용

채팅 엔드포인트는 tools 필드를 허용합니다. GLM 내부의 <tool_call> 형식으로 생성된 도구 표현은 응답에서 OpenAI 호환 tool_calls로 변환됩니다. 따라서 클라이언트 애플리케이션은 일반적인 도구 호출 루프를 사용할 수 있습니다. 도구 정의를 제출하고, 어시스턴트의 도구 호출을 확인한 뒤 함수를 실행하고, 도구 결과를 다른 메시지로 다시 전송하면 됩니다.

컨텍스트 및 서버 인수 조정

이미지 이름 뒤에 배치한 인수는 서버 명령에 추가되며, 마지막 값이 적용됩니다. 예를 들어 65,536 토큰 KV 캐시를 사용하려면 다음과 같이 실행합니다.

docker run -d \
  --name glm53-64k \
  --gpus '"device=0"' \
  --ulimit memlock=-1 \
  --shm-size 16g \
  -p 30000:30000 \
  -v /data/GLM-5.3-Flash-exl3-3.05bpw:/models \
  ghcr.io/0xsero/glm53-flash-offload@sha256:bb633b0bcb85573ad40b6c408af5e1036ae062c593e42479f4e4d2ab521e551d \
  -cs 65536

더 작은 KV 캐시를 사용하면 전문가 캐시 슬롯을 더 많이 확보할 수 있습니다. 게시된 벤치마크 구성에서는 131,072 토큰 KV 캐시, 최대 배치 크기 8, 청크 크기 8,192를 사용했습니다.

Docker 없이 설치

네이티브 설치에는 대상 GPU용으로 빌드된 exllamav3 1.5.1이 필요합니다. 프로젝트를 복제한 후 확장 기능 설치 프로그램을 실행하고, 저장소 및 모델 경로를 설정한 상태에서 제공된 엔트리포인트를 시작합니다.

scripts/install.sh
GLM53_ROOT=$PWD \
GLM53_MODEL_DIR=/path/to/model \
docker/entrypoint.sh

설치 프로그램은 프로젝트의 사용자 지정 확장 기능을 빌드합니다. Docker는 CUDA, PyTorch, Triton, SGLang, exllamav3, 프로젝트 커밋, 테스트된 서버 구성을 고정하므로 가장 재현성이 높은 방법입니다.

품질 및 성능 검증

참조 패널 점수 측정

저장소를 복제한 뒤 포함된 표준 라이브러리만 사용하는 벤치마크 클라이언트를 실행합니다.

python3 bench/score_ref_panel.py \
  --url http://127.0.0.1:30000 \
  --panel reference/glm-5.3-flash-exl3-ref-panel.json \
  --out score.json

교사 강제 패널은 빠른 모드와 정확 모드 모두에서 top-1 일치율 1.0000 및 KL 0을 보고해야 합니다. 이 패널은 프리필 또는 교사 강제 경로를 평가하며, 빠른 모드의 자기회귀 디코딩이 정확하다는 것을 입증하지는 않습니다.

속도 측정 실행

python3 bench/sweep.py \
  --url http://127.0.0.1:30000 \
  --card rtx-3090-24gb/glm-5.3-flash-offload \
  --template glm \
  --config "bb633b0b fast" \
  --prefill 8192 32768 \
  --conc 1 2 4 \
  --reps 3 \
  --dec-reps 2 \
  --no-early-exit \
  --out sweep.json

스트리밍 전달 확인

python3 bench/stream_rate.py --url http://127.0.0.1:30000

성공한 결과에서는 응답의 약 절반이 마지막에 한꺼번에 나타나는 대신 텍스트가 일정하게 도착해야 합니다.

고급 튜닝

CPU 계층 크기 설정

기본적으로 GLM53_CT_CPUS=auto는 물리 코어당 논리 CPU 하나를 선택하고, 운영 체제와 GPU를 구동하는 Python 스레드가 사용할 수 있도록 처음 두 개의 물리 코어를 남겨 둡니다. 측정에 사용한 24코어 호스트에서는 그 결과 CPU 2부터 23까지와 워커 스레드 22개가 사용되었습니다.

명시적으로 할당하려면 다음과 같은 값을 설정합니다.

-e GLM53_CT_CPUS=2-23 \
-e GLM53_CT_THREADS=22

CPU 비용 모델은 22개 스레드에서 전문가당 0.104밀리초로 측정된 GLM53_CT_B를 사용합니다. 워커 스레드가 N개라면 README에서는 이를 0.104 x 22 / N으로 추정할 것을 권장합니다. 예를 들어 두 코어를 비워 둔 16코어 호스트는 워커 스레드 14개와 약 0.16의 값을 사용합니다.

물리 코어가 약 12개 미만이면 대부분의 캐시 미스가 PCIe 경로로 돌아가 성능이 정확 모드에 가까워질 것으로 예상됩니다. 이 경우에는 정확 모드가 더 나은 선택일 수 있습니다.

CPU 계층 메모리 배치 제어

GLM53_CT_SWZ=1은 CPU 계층이 전문가의 블록 연속 복사본을 별도로 사용하도록 합니다. 이는 측정된 고속 구성으로, RAM 사용량이 약 114.2GB 증가합니다. 이를 0으로 설정하면 CPU 계층이 고정된 원본 복사본을 직접 읽으므로 메모리 사용량이 크게 줄어들지만, 프로젝트 보고에 따르면 CPU 전문가 커널 벤치마크는 약 40% 느려집니다. 이 설정의 종단 간 성능은 측정되지 않았습니다.

캐시 예약 공간 조정

GLM53_EC_RESERVE_GB는 전문가 캐시를 할당한 후 VRAM을 여유 공간으로 남겨 둡니다. 기본값은 고속 모드에서 1.5GB, 정확 모드에서 1.0GB입니다. 긴 프리필에서 메모리가 부족해지지 않는 한 고속 모드 예약 공간은 1.5GB로 유지합니다.

GLM53_EC_ELASTIC_GB의 기본값은 10GB입니다. 이만큼의 캐시 메모리를 프리필 활성화와 스테이징에 사용하도록 해제한 뒤 디코드에 다시 확보할 수 있습니다. GLM53_EC_STAGE_GB의 기본값은 스테이징 버퍼당 2.6GB이며, 오버랩을 위해 두 개의 버퍼가 사용됩니다.

더 큰 GPU 사용

전문가 캐시는 모델을 로드하고 구성된 예약 공간을 적용한 후 사용 가능한 VRAM을 기준으로 크기가 결정됩니다. 따라서 32GB 또는 48GB 카드는 더 많은 전문가 슬롯을 할당받으며, 이에 따라 적중률이 높아지고 디코드 성능이 향상될 수 있습니다. README에는 이러한 대용량 카드의 결과가 제공되지 않습니다.

RTX 4090은 포함된 sm_86 빌드를 실행할 수 있지만 측정되지는 않았습니다. Blackwell은 다음 설정으로 다시 빌드해야 합니다.

TORCH_CUDA_ARCH_LIST="8.6;12.0"

다른 아키텍처에서는 새로운 Triton 고정 버전이 필요할 수도 있습니다. 새 고정 버전을 만들 경우, 기준 패널이 여전히 top-1 1.0000 및 KL 0을 유지하는지 확인합니다.

정확한 Triton 선택 보호

이미지는 data/triton_pin_exact.json을 통해 KDA 선형 어텐션 프리필 커널 선택을 고정합니다. Triton이 다른 구성을 선택하도록 두면 부동 소수점 반올림이 달라질 수 있습니다. 기준과 동일한 프리필 동작이 중요하다면 GLM53_TRITON_PIN을 기본값으로 유지합니다.

오프로딩 파이프라인 작동 방식

  1. 라우팅된 전문가를 고정 호스트 메모리에 로드합니다. 각 계층은 정확한 크기의 고정 메모리 영역을 할당받고, exllamav3의 전문가 포인터는 CUDA UVA 별칭을 참조합니다.
  2. VRAM에 탄력적인 CLOCK 캐시를 채웁니다. 라우터 선택 항목을 중복 제거하고 캐시 적중을 표시한 다음, 승인된 캐시 미스에 사용할 교체 대상을 선택합니다.
  3. 캐시되지 않은 전문가를 PCIe를 통해 읽습니다. exllamav3의 커널은 동기식 호스트 측 복사 없이 고정 호스트 표현에 액세스할 수 있습니다.
  4. 긴 프리필을 스테이징합니다. 계층별 선택 수가 충분히 크면 이전 계층이 계산하는 동안 한 계층 앞서 누락된 전문가를 스테이징 버퍼로 복사합니다.
  5. 고속 모드에서 선택된 디코드 캐시 미스를 분할합니다. 비용 모델은 더 따뜻한 캐시 미스를 제로 카피 GPU 실행으로 보내고, 선택된 차가운 캐시 미스는 CPU 계층으로 보냅니다.
  6. CPU와 GPU 결과를 결합합니다. CPU는 고정 매핑 메모리를 통해 작업 결과를 게시하고, GPU는 호스트 동기화 대신 디바이스 측 플래그를 기다린 후 결과로 생성된 FP32 부분 결과를 더합니다.

운영 시 주의 사항

  • 디코드 출력이 기본 exllamav3와 일치해야 한다면 GLM53_MODE=exact를 사용합니다.
  • 스트리밍 지연 시간이 중요하다면 이전 sha256:1159044a... 이미지를 사용하지 마세요. 문서화된 sha256:bb633b0b... 다이제스트를 사용합니다.
  • 현재 고속 모드는 호스트 RAM에 두 개의 전문가 복사본을 유지합니다. 컨테이너를 시작하기 전에 충분한 메모리를 확보하세요.
  • 더 느린 PCIe 링크에서 측정된 RTX 3090 처리량이 그대로 나온다고 가정하지 마세요. 디코드 속도는 캐시 미스 트래픽에 민감합니다.
  • 컨텍스트 크기, 캐시 예약 공간, 동시성 또는 스테이징 설정을 변경할 때 /stats, 시스템 메모리 및 GPU 메모리를 모니터링하세요.
  • 서버는 텍스트만 처리하며, 이 배포에서는 이미지 입력을 지원하지 않습니다.

결론

glm53-flash-offload는 고정 호스트 저장소, 제로 카피 PCIe 읽기, 탄력적인 VRAM 캐시, 스테이징된 프리필 전송 및 선택적 AVX2 CPU 계층을 결합하여 비정상적으로 큰 혼합 전문가 체크포인트를 단일 24GB GPU에서 실용적으로 실행할 수 있게 합니다. 고정된 Docker 이미지로 시작하고, 출력 충실도가 필요하면 정확 모드를, 처리량이 필요하면 고속 모드를 선택한 다음, 캐시 또는 CPU 설정을 조정하기 전에 포함된 품질, 속도 및 스트리밍 검사로 설치를 검증하세요.