Loading the catalog…
Loading the catalog…
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 빠른 격리 LLM 서빙 환경에서 사용자/팀(Tenant)별 인증·인가 및 사용량 제한(Rate Limiting & Quota)을 vLLM 같은 백엔드 추론 엔진에 직접 맡기는 것은 불가능합니다(대부분의 오픈소스 추론 엔진은 OpenAI 규격의 API 서빙 기능만 제공하며 Auth/Accounting 레이어가 없음). 따라서 추론 엔진 앞단에 LLM 전용 AI Gateway 를 배치하고, 백엔드로 Redis 및 저장소를 연동하는 아키텍처가 표준 베스트 프랙티스입니다. 가장 널리 쓰이는 표준 조합은 LiteLLM Proxy , Envoy / Kong , 또는 Portkey 기반 아키텍처입니다. 1. 표준 아키텍처 구성 [Client / Tenant A] ──(API Key A)──┐ ▼ [Client / Tenant B] ──(API Key B)──▶ [ AI Gateway (LiteLLM Proxy) ] ──▶ [ Redis ] (토큰 버킷/사용량 계량) │ ├── /v1/chat/completions (model: qwen3-32b) ──▶ vLLM #1 (GPU 0~3, :8001) └── /v1/chat/completions (model: deepseek) ──▶ vLLM #2 (GPU 4~7, :8002) 2. 컴포넌트별 구현 방안: 인증 및 인가 (AuthN / AuthZ) 1 API Key 기반 테넌트 인증 (가장 일반적) 게이트웨이가 고유한 가상 API Key( sk-team-a-... , sk-team-b-... )를 발급하고, 이 키를 특정 팀/유저 메타데이터와 매핑합니다. 인증(AuthN): Authorization: Bearer sk-... 헤더 검증 인가(AuthZ - 모델 접근 제어): 테넌트 A는 qwen3-32b , bge-m3 모델만 호출 가능 테넌트 B(연구팀)는 고비용의 deepseek-r1 까지 호출 가능하도록 라우팅 제어 2 사내 IdP 연동 (SSO / OAuth2 / JWT) 사내 Keycloak, Okta, 또는 LDAP/Active Directory와 연동하는 경우: 클라이언트는 Bearer JWT 토큰을 전달하고, Gateway가 JWT의 Claim(예: groups , sub , roles )을 파싱하여 테넌트를 식별하고 인가를 수행합니다. 3. 사용량 제한 (Rate Limiting & Quota) 설계 LLM의 부하 제어는 일반 웹 API(RPM 중심)와 완전히 다릅니다. RPM(Requests Per Minute), TPM(Tokens Per Minute), TPD(Tokens Per Day) / 비용 한도 를 계층적으로 통제해야 합니다. 제어 항목 목적 기준 RPM (Requests Per Min) 추론 엔진의 큐 폭주(Queue Starvation) 방지 동시 처리 요청 수 제어 TPM (Tokens Per Min) KV Cache 고갈 및 순간 연산량 폭증 방지 입력 프롬프트 + 출력 생성 토큰 합산 TPD / Budget ($/일, $/월) 특정 팀의 일방적인 GPU 자원 독점 방지 일간/월간 누적 토큰 또는 환산 비용 4. 구현 실전 예시: LiteLLM Proxy 설정 오픈소스 기반으로 가장 빠르고 안정적으로 멀티테넌시를 구축할 수 있는 LiteLLM Proxy + Redis 기준 설정 예시입니다. 1) config.yaml 정의 model_list: # 백엔드 vLLM #1 (Qwen3-32B) - model_name: qwen3-32b litellm_params: model: openai/qwen3-32b api_base: http://localhost:8001/v1 api_key: "none" # 백엔드 vLLM #2 (DeepSeek-R1) - model_name: deepseek-r1 litellm_params: model: openai/deepseek-r1 api_base: http://localhost:8002/v1 api_key: "none" general_settings: master_key: "sk-admin-master-key-here" # 게이트웨이 관리자 키 database_url: "postgresql://user:pass@localhost:5432/litellm" # 키/유저 영구 저장소 redis_url: "redis://localhost:6379" # 분산 Rate Limiting용 캐시 2) 게이트웨이 기동 docker run -d \ -v $(pwd)/config.yaml:/app/config.yaml \ -p 8000:4000 \ ghcr.io/berriai/litellm:main-latest \ --config /app/config.yaml 3) 관리자 API로 테넌트별 API Key 및 쿼터 생성 팀 A (일반 서비스팀 - Qwen만 사용 가능, 엄격한 쿼터 적용): curl -X POST 'http://localhost:8000/key/generate' \ -H 'Authorization: Bearer sk-admin-master-key-here' \ -H 'Content-Type: application/json' \ -d '{ "user_id": "service_team_a", "models": ["qwen3-32b"], "max_budget": 100, # 예산 한도 ($ 또는 환산 단위) "rpm_limit": 60, # 분당 60회 요청 제한 "tpm_limit": 100000, # 분당 10만 토큰 제한 "duration": "30d" }' # 반환된 가상 키(sk-...)를 팀 A에 배포 팀 B (연구/코어팀 - 전 모델 허용, 높은 쿼터): curl -X POST 'http://localhost:8000/key/generate' \ -H 'Authorization: Bearer sk-admin-master-key-here' \ -H 'Content-Type: application/json' \ -d '{ "user_id": "research_team_b", "models": ["qwen3-32b", "deepseek-r1"], "rpm_limit": 300, "tpm_limit": 500000 }' 5. 선점 방지(Noisy Neighbor)와 백엔드 보호 기법 게이트웨이의 계량 기능 외에, 특정 테넌트가 B300 노드의 VRAM 전체를 고갈시키는 것을 막기 위해 추론 엔진 레벨에서도 방어벽을 세워야 합니다. 최대 컨텍스트 길이( --max-model-len ) 강제: 아무리 쿼터를 걸어도 단일 요청에서 수십만 토큰짜리 프롬프트를 밀어 넣으면 엔진의 KV Cache가 즉시 고갈되어 타 테넌트 요청이 큐에 대기(Waiting)됩니다. vLLM 기동 시 --max-model-len 32768 등으로 현실적인 한도를 강제합니다. 동시 디코딩 시퀀스 상한( --max-num-seqs ): 한 번에 처리할 수 있는 최대 배치 크기를 128~256 수준으로 제한하여 스케줄러 큐의 공평성(Fairness)을 유지합니다. HTTP 429 Retry-After 헤더 활용: 게이트웨이에서 특정 테넌트가 TPM/RPM 한도에 도달하면 429 Too Many Requests 와 함께 Retry-After: 3 헤더를 내려주어 클라이언트 SDK가 지수 백오프(Exponential Backoff)를 수행하도록 유도합니다. 네, 가능합니다. 엔터프라이즈 환경에서는 개발자/서비스팀마다 수동으로 API Key를 발급하기보다 사내 IdP(Keycloak, Microsoft Entra ID / Active Directory, Okta 등)와 연동하여 OAuth2/OIDC JWT Bearer 토큰 으로 인증 및 인가를 처리하는 구조가 표준입니다. 구현 방식은 크게 AI Gateway 내장 OIDC 기능 활용 과 앞단 Reverse Proxy(Envoy/Kong) 계층 분리 의 두 가지 패턴으로 나뉩니다. 아키텍처 흐름 (OIDC / OAuth2 Bearer Flow) [클라이언트/사내 유저] │ │ 1. 인증 요청 (Client Credentials 또는 사내 계정 SSO) ▼ [Keycloak / AD (IdP)] ──(유저 그룹/권한/부서 클레임 포함)──▶ Access Token (JWT) 발급 │ │ 2. API 호출 (Authorization: Bearer <JWT>) ▼ [AI Gateway (LiteLLM Proxy 등)] │ ├─▶ 3. JWKS 검증 (서명 검증, 만료 확인) ├─▶ 4. JWT Claim 파싱 (sub=팀ID, groups=부서명, scope 등) ├─▶ 5. Redis 기반 Dynamic Quota 체크 (해당 부서/팀의 TPM/RPM 잔여량) │ ▼ (정상 통과 시) [vLLM 추론 인스턴스 (B300)] 1. Keycloak / AD 사전 세팅 (IdP 설정) 사내 Keycloak(또는 Azure AD / On-Prem AD FS)에서 다음을 구성합니다. Client 생성: Client ID : ai-inference-platform Client Authentication : On (Service Account 기반 머신-투-머신 통신 시) Standard Flow (유저 인터랙티브 로그인용) 또는 Service Accounts Roles (서버-투-서버 연동용 client_credentials ) Token Mapper (Claim) 추가: JWT 페이로드에 팀명, 부서 코드, 또는 그룹 정보가 들어가도록 설정합니다. 예: groups: ["data-platform-team", "ai-research"] 또는 department: "sre" 2. 구현 방식 A: LiteLLM Proxy 자체 OIDC/JWT 검증 연동 LiteLLM은 수신된 Authorization: Bearer <JWT> 헤더를 사내 IdP의 JWKS(Public Key) 엔드포인트로 직접 검증할 수 있습니다. config.yaml 설정 예시 model_list: - model_name: qwen3-32b litellm_params: model: openai/qwen3-32b api_base: http://localhost:8001/v1 - model_name: deepseek-r1 litellm_params: model: openai/deepseek-r1 api_base: http://localhost:8002/v1 general_settings: master_key: "sk-admin-master-key" redis_url: "redis://localhost:6379" router_settings: # Keycloak / AD의 OIDC 설정 jwt_auth: # Keycloak의 JWKS URL (서명 공개키 자동 갱신) jwks_url: "https://keycloak.company.com/realms/corp-realm/protocol/openid-connect/certs" # 토큰의 Issuer 검증 expected_issuer: "https://keycloak.company.com/realms/corp-realm" # 토큰의 Audience 검증 expected_audience: "ai-inference-platform" # 테넌트 식별자로 사용할 JWT Claim 필드 (예: client_id, sub, 또는 커스텀 클레임) user_id_jwt_field: "preferred_username" # 팀/부서 식별용 Claim (그룹 매핑) team_id_jwt_field: "department" 동적 인가 및 사용량 정책 (Tier 매핑) JWT의 특정 Claim(예: department )에 따라 허용 모델과 쿼터를 Gateway 데이터베이스에 사전 정의해 둘 수 있습니다. 사전 등록 정책 예시 (API로 등록): # 'data-sre' 부서에 대한 기본 쿼터 및 접근 모델 정의 curl -X POST 'http://localhost:8000/team/new' \ -H 'Authorization: Bearer sk-admin-master-key' \ -H 'Content-Type: application/json' \ -d '{ "team_id
What RADAR observed and classified to build this opportunity. It is what the source published, not a verification that the offer is still active.
26O01c. 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장이 단일…
Open source