Загружаем каталог…
Загружаем каталог…
NVIDIA B300(Blackwell Ultra, 단일 GPU당 HBM3e 288GB 탑재) 8장으로 구성된 단일 노드는 총 VRAM만 약 2.3TB 에 달하며, 5세대 NVLink(양방향 1.8TB/s per GPU)로 풀메시(Full-mesh) 연결되어 있습니다. 단일 노드 내에서 여러 모델(예: DeepSeek 계열, Qwen3-32B, 경량 임베딩/리랭커 등)을 동시에 서빙할 때 NVLink 토폴로지 유지, VRAM/KV Cache 고립, 엔진 서빙 아키텍처 및 메트릭 관측성 관점에서의 베스트 프랙티스는 다음과 같습니다. 1. GPU 토폴로지 기반 자원 파티셔닝 (Tensor Parallelism 분할) B300 8-way 노드는 NVLink Switch를 통해 8장이 단일 패브릭으로 묶여 있지만, 여러 모델을 동시에 쪼개어 서빙할 때는 NUMA 노드와 PCIe/NVLink 도메인 에 맞춰 2의 거듭제곱 단위( TP=1 , 2 , 4 , 8 )로 격리해야 All-Reduce 병목이 발생하지 않습니다. 권장 모델 배치 시나리오 케이스 A: 초대형 MoE 1개 + 중소형 모델 병행 (가장 흔한 멀티모델 패턴) GPU 0~3 (TP=4): DeepSeek-R1-Distill-70B 또는 중대형 MoE 모델 (4장 × 288GB = 1.15TB VRAM 풀) GPU 4~5 (TP=2): Qwen3-32B / Llama 계열 메인 LLM 추론 (2장 × 288GB = 576GB VRAM) GPU 6 (TP=1): 경량 7B~14B 모델 또는 코드 전용 LLM GPU 7 (TP=1): 임베딩(Embedding) + 리랭커(Reranker) 전용 인스턴스 (vLLM 또는 TEI) 케이스 B: DeepSeek-R1 Full (FP8/FP4) 전용 서빙 DeepSeek 671B MoE 가중치(FP8 기준 약 700GB)는 단일 노드 8장(TP=8, EP=8)으로 VRAM에 완전히 올릴 수 있으므로, 멀티 테넌트보다는 단일 노드 전체를 전용으로 할당하는 것이 성능상 유리합니다. CPU & NUMA Affinity 바인딩 (필수) 8장 노드는 통상 듀얼 소켓 CPU(NUMA 0, NUMA 1) 구조입니다. 모델 서빙 프로세스가 GPU뿐만 아니라 대응하는 NUMA 노드의 CPU 코어/메모리에 정확히 고정되어야 인터커넥트 병목이 없습니다. # 예: GPU 0~3번은 NUMA node 0번에 고정하여 vLLM 인스턴스 기동 numactl --cpunodebind=0 --membind=0 vllm serve /models/Qwen-70B \ --tensor-parallel-size 4 \ --gpu-memory-utilization 0.90 \ --port 8001 2. 추론 엔진(Engine) 및 메모리 격리 전략 여러 추론 프로세스가 동일 물리 노드에 공존할 때 OOM(Out of Memory) 연쇄 장애를 막는 설정입니다. CUDA_VISIBLE_DEVICES 하드웨어 격리: 각 서빙 컨테이너(또는 프로세스)에는 사용할 GPU 인덱스만 노출시킵니다. Container A: CUDA_VISIBLE_DEVICES=0,1,2,3 Container B: CUDA_VISIBLE_DEVICES=4,5 --gpu-memory-utilization 고정 및 KV Cache 버퍼 제어: vLLM/SGLang은 기본적으로 GPU 메모리의 90% 이상을 가중치 + KV Cache 블록으로 사전 선점(Pre-allocate)합니다. 멀티 프로세스 환경에서는 프레임워크 오버헤드, PyTorch CUDA 컨텍스트, PagedAttention 관리 버퍼를 고려하여 0.85 ~ 0.90 수준으로 설정해 메모리 스파이크를 방지합니다. MIG(Multi-Instance GPU) vs 프로세스 기반 분할: B300에서는 가급적 MIG 대신 vLLM 단일 컨테이너 단위 분할 권장: MIG를 활성화하면 NVLink 대역폭 활용이 제한되고 Tensor Parallelism 제약이 생깁니다. LLM 추론은 NVLink를 온전히 활용할 수 있도록 베어메탈/컨테이너 레벨에서 GPU 카운트 단위( TP=1, 2, 4 )로 물리 카드를 분배하는 것이 좋습니다. 3. 라우팅 및 동적 부하 분산 (Front Gateway) 노드 1대 내부에서 모델별로 각기 다른 포트(8001, 8002, 8003...)로 엔진이 뜨게 되므로, 앞단에 경량 AI 게이트웨이를 배치해야 클라이언트 관리가 단순해집니다. Reverse Proxy / Gateway: Litellm , Envoy , 또는 Traefik 포트 8000 단일 엔드포인트 노출 후 요청 헤더/바디의 model 필드에 따라 로컬 포트로 라우팅: "model": "qwen3-32b" $\rightarrow$ localhost:8001 "model": "deepseek-r1-distill-70b" $\rightarrow$ localhost:8002 "model": "bge-reranker" $\rightarrow$ localhost:8003 Prefix Caching 활성화: 동일 모델에 반복되는 시스템 프롬프트(System Prompt)가 많다면 --enable-prefix-caching 을 켜서 중복 토큰 연산과 KV Cache 소비를 40~60% 절감합니다. 4. 모니터링 및 관측성(Observability) 파이프라인 단일 노드 멀티 모델 환경에서는 "어느 모델이 어느 GPU 대역폭을 잠식하고 있는지"를 즉각 분리해 관측해야 합니다. [B300 GPUs] ──> DCGM Exporter (포트 9400) ──┐ [vLLM #1] ──> Prometheus 메트릭 (8001) ──┼──> Prometheus Server ──> Grafana Dashboard [vLLM #2] ──> Prometheus 메트릭 (8002) ──┘ A. 하드웨어 레벨: NVIDIA DCGM Exporter (Blackwell 지원 버전) 포트: 기본 9400 필수 감시 메트릭: DCGM_FI_DEV_GPU_UTIL : GPU 연산 코어 가동률 DCGM_FI_DEV_MEM_COPY_UTIL : HBM3e 메모리 대역폭 포화 여부 DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL : GPU 간 All-Reduce 교환량 (TP 분할 모델 정상 동작 검증) DCGM_FI_DEV_POWER_USAGE / DCGM_FI_DEV_GPU_TEMP : B300 노드 고전력/열 부하 감시 B. 서빙 엔진 레벨: vLLM / SGLang 내장 Prometheus 메트릭 각 vLLM 인스턴스는 자체 포트(예: :8001/metrics , :8002/metrics )로 상세 메트릭을 노출합니다. KV Cache 포화도: vllm:gpu_cache_usage_factor : 가장 중요. 0.85 이상 지속 시 새 요청이 큐에 쌓이며 TTFT(Time to First Token) 지연 급증. 대기열 병목: vllm:num_requests_waiting : 요청이 처리되지 못하고 큐에 머무는 수. 0보다 크면 동시 요청 처리 한계 도달을 의미. vllm:num_requests_running : 현재 PagedAttention으로 동시 디코딩 중인 배치 크기. 처리 성능(Latency & Throughput): vllm:time_to_first_token_seconds : 초기 Prefill 지연 시간. vllm:time_per_output_token_seconds : 디코딩 토큰 생성 간격 (사용자 체감 속도). 5. 핵심 운용 체크리스트 점검 영역 권장 설정값 / 액션 목적 NUMA 바인딩 numactl --cpunodebind=X --membind=X 소켓 간 PCIe 크로스오버 통신 억제 GPU 격리 컨테이너별 CUDA_VISIBLE_DEVICES 명시 프로세스 간 VRAM 침범 및 충돌 방지 KV Cache --gpu-memory-utilization 0.85~0.90 PagedAttention 할당 버퍼 확보로 OOM 방지 멀티 모델 분할 TP 크기는 2의 제곱수( 1, 2, 4, 8 ) 유지 NVLink 전송 효율 최적화 및 비대칭 링 방지 로그 수집 vLLM Engine 에러 로그와 DCGM XID 수집 하드웨어 ECC 에러 및 엔진 Crash 빠른 격리 == 네. B300 8장짜리 단일 GPU 노드에서 여러 LLM을 동시에 서비스 하려면, 단순히 모델마다 GPU를 1~2장씩 고정 배정하는 것보다 GPU partitioning + inference scheduler + QoS + observability 를 함께 설계하는 게 좋습니다. 특히 지금 말씀하신 환경처럼 B300 8-GPU 서버에서 여러 모델의 inference benchmark → 실제 서비스 로 가져가려는 경우라면, 저는 아래 구조를 권합니다. 권장 기본 구조 Client │ ┌──────▼──────┐ │ API Gateway │ │ / Router │ └──────┬──────┘ │ ┌────────────┴────────────┐ │ │ Model A / 70B Model B / 8B BF16/FP8 FP8/FP4 │ │ ┌──────▼──────┐ ┌──────▼──────┐ │ Triton / │ │ Triton / │ │ vLLM / TRT │ │ vLLM / TRT │ └──────┬──────┘ └──────┬──────┘ │ │ GPU 0-3 GPU 4 GPU 4-7 GPU 5 GPU 6/7 ... 핵심은 "모델 → GPU"를 정적으로만 매핑하지 말고, 모델별 QoS를 정의한 후 그에 맞춰 GPU를 배치 하는 것입니다. 1. 가장 먼저 GPU를 모델별로 논리적으로 나누는 게 좋습니다 B300 8장이라면 처음부터 모든 GPU를 하나의 거대한 pool로 보고 스케줄링하기보다는 다음처럼 GPU pool 을 만드는 것을 추천합니다. 예를 들어: Pool GPU 용도 Pool-A 0-3 70B급 모델 Pool-B 4 8B/14B Pool-C 5 8B/14B Pool-D 6-7 실험/Batch/대형 모델 또는 모델이 많다면: GPU 0-3 : Large Model Pool GPU 4 : Small Model A GPU 5 : Small Model B GPU 6 : Small Model C GPU 7 : Experimental / overflow 이렇게 하면 작은 모델 하나 때문에 4~8 GPU짜리 모델의 inference가 영향을 받는 상황을 줄일 수 있습니다. 2. 모델별 GPU 개수는 "모델 크기"보다 TP scaling으로 결정 예를 들어: 70B TP=4 GPU 0-3 8B TP=1 GPU 4 32B TP=2 GPU 5-6 이런 식입니다. 특히 B300에서는 TP=1/2/4/8을 모두 측정한 후 결정 하는 게 중요합니다. 현재 진행하시는 benchmark matrix: TP = 1 / 2 / 4 / 8 Precision = BF16 / FP8 / FP4 Context = ... Concurrency = ... 결과를 이용해서 각 모델의 "최적 GPU 수" 를 결정하면 됩니다. 예: Model TP GPU Max Throughput ------------------------------------------------ Llama-8B 1 1 1,200 tok/s Qwen-32B 2 2 700 tok/s Llama-70B 4 4 520 tok/s DeepSeek-R1-70B 4 4 480 tok/s GPT-OSS-120B 4 4 430 tok/s 그러면 8 GPU에서 어떤 모델을 동시에 돌릴지 계산할 수 있습니다. 3. 중요한 것은 GPU utilization이 아니라 "GPU memory + KV cache" LLM 여러 개를 동시에 돌릴 때 흔히: GPU utilization 70% 만 보고 판단하는데, 이것만 보면 상당히 위험합니다. 반드시 다음을 같이 봐야 합니다. GPU memory used GPU memory free KV cache usage KV cache hit rate KV cache eviction SM utilization Tensor Core utilization HBM bandwidth PCIe/NVLink/NVSwitch traffic 특히 inference에서는: Weights + KV Cache + CUDA Graph + Runtime workspace + Activation 이 전부 GPU memory를 사용합니다. 그래서 모델별로 memory budget을 명시적으로 설정 하는 게 좋습니다. 예: GPU 0-3 Model A weights 280 GB KV cache 80 GB workspace 20 GB reserve 20 GB total 400 GB 그리고 절대로 100%까지 채우지 않습니다. 실서비스라면 대략: Target: GPU memory 70~80% Warning: 80~85% Critical: >90% 정도로 운영하는 것이 안전합니다. 정확한 threshold는 B300의 실제 HBM 용량과 사용하는 inference engine에 맞춰 잡아야 합니다. 4. 작은 모델은 GPU 하나에 여러 모델을 넣을 수도 있음 이 부분이 상당히 중요합니다. 예를 들어: GPU 4 Model B 8B Model C 7B Model D embedding 처럼 할 수 있습니다. 하지만 이것을 무작정 하면 안 됩니다. 특히: Model B → high concurrency Model C → high concurrency Model D → batch 가 동시에 들어오면 서로 GPU를 잡아먹습니다. 그래서 GPU sharing은 workload class까지 같이 나눠야 합니다. 추천: GPU 4 ┌────────────────────────────┐ │ Model B │ │ latency-sensitive │ │ priority = 100 │ ├────────────────────────────┤ │ Model C │ │ normal │ │ priority = 50 │ ├────────────────────────────┤ │ Embedding │ │ batch │ │ priority = 10 │ └────────────────────────────┘ 5. 가능하면 MIG보다 먼저 "process/container isolation"을 검토 B300에서 GPU partitioning을 생각하면 MIG가 먼저 떠오를 수 있습니다. 하지만 LLM inference에서는 무조건 MIG가 좋은 것은 아닙니다. 특히: 70B TP=4 NVLink/NVSwitch KV cache large batch 같은 workload에서는 GPU 전체를 사용하는 편이 훨씬 유리할 수 있습니다. 따라서 저는: Large model Full GPU Small model Full GPU + multiple inference processes Strict isolation이 필요한 경우 MIG 순서로 검토하겠습니다. 6. Kubernetes에서는 "GPU를 누가 소유하는가"를 명확히 해야 함 지금 환경이 Kubespray + NVIDIA GPU Operator이므로 Kubernetes로 운용한다면 특히 중요합니다. 기본적으로: Pod └── GPU resource request 를 사용합니다. 예: resources: limits: nvidia.com/gpu: 4 그러면 Kubernetes가 GPU 4장을 할당합니다. 하지만 여러 모델을 한 GPU에 공유하려면 별도의 전략이 필요합니다. 그래서 모델별 GPU allocation policy 를 먼저 정하는 게 좋습니다. 예: large-model gpu: 4 priority: high medium-model gpu: 2 priority: normal small-model gpu: 1 priority: normal batch gpu: 1 priority: low 7. Triton을 중심으로 잡는 것도 좋은 선택 현재 B300 benchmark를 하고 있으니 저는 실제 서비스 구조에서는 Triton을 상당히 유력하게 봅니다. 구조는: API Gateway │ ▼ Model Router │ ┌────────────┼────────────┐ ▼ ▼ ▼ Model A Model B Model C Triton Triton Triton │ │ │ GPU0-3 GPU4 GPU5 Triton의 장점은: model repository dynamic batching concurrent execution metrics model lifecycle Kubernetes integration 여러 backend 지원 등입니다. 다만 LLM 자체의 scheduler/KV cache 최적화는 vLLM/TensorRT-LLM 등 engine의 특성이 더 중요 하기 때문에, Triton + TensorRT-LLM 또는 Triton + vLLM backend 같은 형태를 모델에 따라 비교하는 것이 좋습니다. 8. 모델별로 "서비스 등급"을 만드는 것을 추천 예를 들어: Class A Interactive SLA 중요 latency 우선 Class B General inference throughput 우선 Class C Batch 비용/throughput 우선 그리고 GPU도: A → GPU 0-3 B → GPU 4-6 C → GPU 7 처럼 배치합니다. 이게 실제 운영에서 상당히 중요합니다. 9. Monitoring은 GPU만 보면 안 됨 제가 추천하는 dashboard는 최소한 다음 구조입니다. GPU dashboard GPU utilization HBM utilization HBM bandwidth Tensor Core utilization Power Temperature PCIe throughput NVLink/NVSwitch throughput ECC/XID LLM dashboard Requests/sec Concurrency TTFT ITL E2E latency Input tokens/sec Output tokens/sec Total tokens/sec Queue time Batch size KV cache utilization KV cache hit ratio OOM Request rejection 특히 TTFT와 ITL 을 반드시 따로 봐야 합니다. TTFT = Time To First Token ITL = Inter Token Latency 예를 들어: TTFT = 2.1 sec ITL = 20 ms 이면 prompt processing 쪽이 문제일 수 있고, TTFT = 100 ms ITL = 200 ms 이면 generation/concurrency 문제가 더 클 수 있습니다. 10. Prometheus metric을 모델별로 분리 현재 Prometheus/Grafana를 사용하고 있으니: model="llama-70b" model="qwen-32b" model="llama-8b" 같은 label을 반드시 넣는 것을 추천합니다. 예: llm_requests_total{ model="llama-70b", precision="fp8", tp="4" } 그리고: llm_ttft_seconds llm_itl_seconds llm_input_tokens_total llm_output_tokens_total llm_kv_cache_usage_ratio llm_queue_depth llm_active_requests 등을 모델별로 수집합니다. 11. 가장 중요한 운영 지표는 "GPU utilization"이 아니라 GPU당 throughput 예를 들어: Model A GPU utilization = 95% throughput = 300 tok/s 과 Model A GPU utilization = 75% throughput = 420 tok/s 라면 후자가 훨씬 좋은 configuration일 수 있습니다. 따라서 모델별로: tokens/sec/GPU 를 만들어야 합니다. 예: Model GPU Throughput tok/s/GPU 8B 1 1,000 1,000 32B 2 700 350 70B 4 520 130 120B 4 430 108 이 지표가 GPU allocation 의사결정의 핵심 이 됩니다. 12. Concurrency별 operating point를 정해야 함 모델마다 무한정 concurrency를 올리면 안 됩니다. 예: Llama-70B Concurrency 1 100 tok/s
То, что RADAR обнаружил и классифицировал для этой возможности. Это опубликованный источником текст, а не подтверждение, что предложение ещё действует.
26S30k. NVIDIA B300(Blackwell Ultra, 단일 GPU당 HBM3e 288GB 탑재) 8장으로 구성된 단일 노드는 총 VRAM만 약 2.3TB 에 달하며, 5세대 NVLink(양방향 1.8TB/s per GPU)로 풀메시(Full-mesh) 연결되어 있습니다. 단일 노드 내에서 여러 모델(예: DeepSeek 계열, Qwen3-32B, 경량 임베딩/리랭커 등)을 동시에 서빙할 때 NVLink 토폴로지 유지, VRAM/KV Cache 고립, 엔진 서빙 아키텍처 및 메트릭 관측성 관점에서의 베스트 프랙티스는 다음과 같습니다. 1. GPU 토폴로지 기반 자원 파티셔닝 (Tensor Parallelism 분할) B300 8-way 노드는 NVLink Switch를 통해 8장이 단일…
Открыть источник