
빌드할 내용
이 프로젝트는 vLLM을 사용해 두 개의 NVIDIA DGX Spark 노드에서 DeepSeek-V4.1-Flash를 제공하기 위한 스크립트를 제공합니다. 텐서 병렬 처리는 QSFP/RoCE 링크를 통해 두 노드에서 실행되며, 헤드 노드는 포트 8000에서 OpenAI 호환 API를 제공합니다.
배포에는 0xSero/DeepSeek-V4.1-Flash-Spark 체크포인트가 사용됩니다. 라우팅된 백본 전문가 가중치는 EXL3 트렐리스 데이터로 인코딩되며, 보고된 가중치당 평균 비트 수는 2.77입니다. 어텐션, 공유 전문가, 라우터, Engram 테이블, 초안 레이어, 비전 구성 요소, 임베딩 및 출력 헤드는 업스트림 체크포인트에서 그대로 유지됩니다.
배포가 완료되면 API를 통해 모델을 직접 사용하거나, Pi 코딩 에이전트에 연결해 코딩 및 도구 지원 워크플로를 구성할 수 있습니다.
성능 및 기능
README에는 RoCE를 통한 텐서 병렬 처리, FP8 KV 캐시, 7토큰 DSpark 추측 디코딩, 디스크 기반 Engram 테이블 및 2개의 동시 시퀀스를 사용한 두 개의 DGX Spark GB10 노드 측정 결과가 보고되어 있습니다.
- 8k 프롬프트 프리필: 초당 약 2,050토큰.
- 32k 프롬프트 프리필: 초당 약 2,061토큰.
- 코드 디코딩: 단일 스트림에서 초당 약 39–41토큰.
- 2개 스트림 코드 디코딩: 총 초당 60토큰.
- 일반 문장 디코딩: 단일 스트림에서 초당 약 29토큰.
- 요청당 최대 컨텍스트: 262,144토큰.
- KV 캐시 풀: 2,023,717토큰.
- 비전 입력, 도구 호출 및 추론: 스모크 테스트 성공.
- 175k 토큰 컨텍스트 리콜: 보고된 6개 실험실 검증 항목 모두 통과.
첫 부팅에는 가중치와 EXL3 뱅크를 로드하고, 커널을 컴파일하며, CUDA 그래프를 캡처하기 때문에 약 11–13분이 걸립니다.
사전 요구 사항
DGX OS를 실행하는 DGX Spark 노드 2개가 필요합니다. 한 노드는 API를 제공하는 헤드로, 다른 노드는 워커로 지정합니다.
- RoCE가 활성화된 상태로 두 노드를 연결하는 QSFP 케이블.
- 각 노드에서
rdma link로 확인한ACTIVE상태의 RDMA 포트 1개 이상. - 각 노드의 해당 패브릭 네트워크에 할당된 IPv4 주소. 예:
10.10.10.13및10.10.10.11. - 워커의 패브릭 주소를 사용한 헤드에서 워커로의 무암호 SSH.
- 두 노드에 설치된 NVIDIA 런타임이 포함된 Docker.
- 사용자가
docker그룹에 속해야 합니다. - 헤드에 약 700GB, 워커에 470GB의 여유 NVMe 공간.
- 두 노드의
python3,rsync및curl. - Pi를 실행할 시스템의 Node.js 및 npm.
저장소 복제 및 워커 정의
헤드 노드에서 다음 명령을 실행합니다. SSH 대상을 워커의 패브릭 주소로 바꾸세요.
git clone https://github.com/0xSero/DeepSeek-V4.1-Flash-Two-Sparks
cd DeepSeek-V4.1-Flash-Two-Sparks
export WORKER=user@10.10.10.11스크립트는 WORKER를 사용해 두 번째 Spark에 연결합니다. 계속하기 전에 SSH 키 인증이 작동하는지 확인하세요.
체크포인트 다운로드 및 배포
헤드의 기본 모델 디렉터리에 약 462GB 크기의 체크포인트를 다운로드합니다.
scripts/download.sh다운로드 스크립트는 Engram 샤드도 다시 조립합니다. Hugging Face는 개별 파일을 50GB로 제한하므로 두 개의 기본 샤드가 .partNN 파일로 저장됩니다. 스크립트는 이를 다시 조립하고, sha256-manifest.txt를 기준으로 6개의 기본 샤드를 검증한 다음 part 파일을 삭제합니다. 해당 파일을 보존하려면 KEEP_PARTS=1을 설정하세요.
완성된 모델을 패브릭을 통해 워커로 복사합니다.
scripts/copy-to-peer.sh또는 워커에서도 scripts/download.sh를 직접 실행할 수 있습니다. 기본 모델 경로는 ~/models/DeepSeek-V4.1-Flash-Spark입니다. 워커에서 다른 경로를 사용하는 경우 실행 전에 WORKER_MODEL_DIR을 설정하세요.
서빙 이미지 가져오기
이 프로젝트는 EXL3 혼합 전문가 경로와 B12X Spark 커널이 포함된 vLLM 이미지를 사용합니다. 두 노드에서 고정된 이미지를 가져옵니다.
docker pull ghcr.io/0xsero/deepseek-v4.1-flash-spark@sha256:5668e35e5ee021da4b9ce88a1964caf0e082e8ca01d81d1d64b6213a55c6add5이미지가 아직 없으면 실행 스크립트가 자동으로 가져오므로 시작 과정에서 이 단계를 수행해도 됩니다.
두 텐서 병렬 순위 실행
헤드에서 2노드 서버를 시작합니다.
scripts/launch.sh런처는 활성 패브릭 인터페이스를 감지하고, ~/.dsv41-two-sparks/api_key에 API 키를 생성하며, 두 노드에서 메모리 가드를 시작하고, 워커에서 순위 1을 실행한 다음 헤드에서 순위 0을 시작합니다. API를 사용할 수 있을 때까지 대기하며 시작에 최대 45분을 허용합니다.
같은 스크립트로 배포 상태를 확인하거나 관리할 수 있습니다.
scripts/launch.sh status
scripts/launch.sh logs r0
scripts/launch.sh logs r1
scripts/launch.sh stop서버는 헤드의 로컬 주소 http://127.0.0.1:8000에서 수신 대기합니다. 클라이언트는 헤드에서 연결 가능한 주소를 사용할 수 있으며, 순위 간 트래픽에는 QSFP/RoCE 패브릭을 사용해야 합니다.
스모크 테스트 실행
다음 명령으로 텍스트 생성, 도구 호출 및 비전 입력을 검증합니다.
python3 scripts/smoke.py http://127.0.0.1:8000각 검사는 PASS 또는 FAIL을 보고합니다. 선택 사항인 벤치마크도 실행할 수 있습니다.
python3 scripts/bench.py --out bench.json --conc 1 2이 벤치마크는 출력 제한을 적용하지 않고 프리필, 디코드 및 긴 컨텍스트 처리 속도를 측정합니다.
OpenAI 호환 엔드포인트 사용
서버는 다음 API 세부 정보를 제공합니다.
- 기본 URL:
http://<head-ip>:8000/v1 - 모델 이름:
deepseek-v4.1-flash - 인증:
~/.dsv41-two-sparks/api_key의 bearer 토큰
예를 들어 다음 명령으로 헤드 노드에서 키를 가져올 수 있습니다.
ssh <head> cat ~/.dsv41-two-sparks/api_key그런 다음 기본 URL, 모델 이름 및 bearer 키를 설정하여 모든 OpenAI 호환 클라이언트에서 이 엔드포인트를 사용할 수 있습니다.
Pi를 모델에 연결
Node.js와 npm이 설치된 머신에서 Pi 프로바이더를 설치하고 등록합니다. 이 명령에는 마지막 모델 경로를 제외한 API 기본 URL을 지정합니다.
pi/install.sh http://<head-ip>:8000/v1Pi를 시작할 셸에서 API 키를 설정합니다.
export DSV41_API_KEY=$(ssh <head> cat ~/.dsv41-two-sparks/api_key)
pi --model dsv41-sparks/deepseek-v4.1-flash설치 프로그램은 PATH에 Pi가 아직 없으면 설치한 다음, Pi의 모델 구성에서 dsv41-sparks 프로바이더만 추가하거나 교체합니다. 먼저 타임스탬프가 포함된 백업을 생성하며 다른 프로바이더는 그대로 둡니다.
enabledModels 목록을 사용하는 경우 설치 프로그램이 해당 목록에 제공되는 모델을 추가합니다. SET_DEFAULT=1로 설정하면 이 모델을 Pi의 시작 모델로 지정할 수 있습니다.
설치된 확장 기능은 이 프로바이더에서 Pi의 출력 토큰 제한을 제거하여 응답이 자연스럽게 종료되도록 합니다. 요청 시점에 DSV41_API_KEY를 읽으며 키를 Pi 구성에 기록하지 않습니다.
기본 구성 이해
scripts/launch.sh는 측정에 사용된 서빙 구성을 재현합니다. 주요 설정은 다음과 같습니다.
KV_BYTES=2700000000으로 설정된 FP8 KV 캐시262144토큰의 최대 컨텍스트 길이- 최대 2개의 동시 시퀀스
2048로 설정된 최대 배치 토큰 수- 7개의 초안 토큰과 적응형 검증을 사용하는 DSpark 추측 디코딩
- 디스크 기반 Engram 테이블
- B12X 어텐션, 선형 및 MoE 커널
ST_EXL3_PREFILL=st로 설정된 EXL3 라우팅 전문가FULL_DECODE_ONLYCUDA 그래프- B12X RoCE 원샷 all-reduce 및 나머지 분산 작업에 사용하는 NCCL over RoCE
- 멀티모달 프롬프트당 이미지 1개
deepseek_v41추론 및 도구 호출 파서
대부분의 설정은 환경 변수로 재정의할 수 있습니다. 모델 디렉터리는 MODEL_DIR, 워커의 모델 디렉터리는 WORKER_MODEL_DIR, 영구 런타임 데이터는 STATE_DIR로 제어합니다. 기본 상태 디렉터리는 ~/.dsv41-two-sparks입니다.
런처는 모델을 /model에 읽기 전용으로 마운트합니다. EXL3 할당 계획을 상태 디렉터리에 복사하고, 마운트된 EXL3 디렉터리를 가리키도록 뱅크 경로를 다시 작성합니다.
올바른 네트워크에서 트래픽 유지
vLLM, NCCL 및 Gloo 프로세스는 Wi-Fi, 이더넷 또는 Tailscale 인터페이스가 아니라 QSFP/RoCE 주소에 바인딩되어야 합니다. 런처는 일반적으로 활성 RoCE 포트를 감지하고 다음과 같은 변수를 설정합니다.
VLLM_HOST_IPNCCL_SOCKET_IFNAMEGLOO_SOCKET_IFNAMENCCL_IB_HCA
자동 감지에서 잘못된 인터페이스를 선택하면 HEAD_IP, WORKER_IP, HEAD_IFNAME, WORKER_IFNAME, HEAD_HCAS 또는 WORKER_HCAS를 명시적으로 설정합니다. 올바른 주소와 RDMA 장치를 확인하려면 ip -br a 및 rdma link를 사용합니다.
메모리를 안전하게 관리
DGX Spark는 CPU와 GPU가 128 GB 메모리 풀을 공유합니다. 사용 가능한 메모리가 0에 도달하면 컨테이너가 정상적으로 종료되는 대신 호스트가 응답하지 않을 수 있습니다. 런처는 두 노드 모두에서 scripts/memguard.sh를 시작하여 사용 가능한 메모리가 구성된 최저 기준 아래로 떨어지면 dsv41-r* 컨테이너를 중지합니다.
메모리 가드 로그는 다음 경로에서 확인할 수 있습니다.
~/.dsv41-two-sparks/memguard.log기본 구성에서 안정 상태의 사용 가능한 메모리는 약 2–3 GiB로 보고됩니다. 가드가 작동하면 MEMGUARD_GIB를 늘리기 전에 KV_BYTES 또는 GPU_UTIL을 낮춥니다.
일반적인 문제 해결
시작이 느림
첫 부팅에서는 가중치를 로드하고, EXL3 뱅크를 준비하고, B12X 커널을 컴파일하고, CUDA 그래프를 캡처하는 동안 약 12분이 걸릴 수 있습니다. 커널 캐시는 STATE_DIR/cache에 저장되므로 이후 실행은 더 빠를 수 있습니다.
Engram 파일이 없음
시작 중 model-00005-of-00006.safetensors와 같은 파일이 없다는 메시지가 표시되면 Engram 샤드가 다시 조립되지 않았을 가능성이 큽니다. scripts/download.sh를 다시 실행합니다. 이 명령은 완료되지 않은 작업을 재개하고 완료된 단계는 건너뜁니다.
패브릭 감지에서 잘못된 인터페이스를 선택함
ip -br a로 주소를 확인하고 rdma link로 RDMA 상태를 확인합니다. 그런 다음 위에서 설명한 헤드 및 워커 인터페이스, IP, HCA 변수를 명시적으로 제공합니다.
다운로드가 느림
Spark가 Wi-Fi를 통해서만 인터넷에 연결되는 경우 업링크가 가장 우수한 노드에서 체크포인트를 다운로드하고 scripts/copy-to-peer.sh를 사용해 패브릭을 통해 전송합니다.
Pi에서 모델이 보이지 않음
Pi를 시작하는 셸과 동일한 셸에서 DSV41_API_KEY를 export했는지 확인합니다. Pi 내부에서 /model을 실행하여 모델 목록을 다시 로드합니다.
Pi 인쇄 모드가 무기한 대기함
표준 입력이 터미널이 아닌 경우 pi -p는 stdin에서도 읽습니다. 스크립트에서는 stdin을 /dev/null로 리디렉션하세요:
pi -p < /dev/null결론
이 저장소에는 두 대의 DGX Spark에서 DeepSeek-V4.1-Flash를 실행하는 데 필요한 모델, 서빙 이미지, 분산 실행 스크립트, 메모리 보호 기능, 검증 도구 및 Pi 통합이 포함되어 있습니다. RoCE 패브릭을 준비하고, 두 노드에서 체크포인트를 다운로드하고 검증한 다음, 두 랭크를 실행하고 스모크 테스트를 수행하세요. 그런 다음 호환 클라이언트 또는 Pi를 헤드 노드의 OpenAI 호환 엔드포인트로 지정하면 됩니다.
