EVA Agent Dependencies
EVA Agent를 실행하기 위해 필요한 의존성(Dependencies) 설치 가이드입니다.
EVA Agent를 설치하기 전에 데이터 저장을 위한 Qdrant(벡터 DB)와 모델 추론을 위한 vLLM 인프라를 먼저 구축해야 합니다.
이 문서에서는 EVA 구동에 필요한 의존성 패키지 설치 방법을 안내합니다.
설치 구조 이해하기
원활한 설치를 위해 패키지 간 설치 순서를 확인하세요.
- eva-agent-init: 스토리지 클래스(Storage Class)를 정의합니다. (가장 먼저 설치)
- qdrant / vllm: 위에서 정의한 스토리지를 사용하여 데이터를 보관합니다.
- eva-agent: 위 서비스가 준비되면 마지막에 설치합니다.
사전 준비 사항
설치에 필요한 CLI 도구가 준비되어 있는지 확인하세요.
-
kubectl: 클러스터 제어 도구 설치
-
helm: 패키지 관리 도구 설치
-
kustomize: 설정 커스텀 도구 (post-render 시 필요)
# kustomize 바이너리 설치 (Linux 기준)
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
chmod +x kustomize
sudo mv kustomize /usr/local/bin/
kustomize version -
On-premise 설정 (AWS/NCP 등 클라우드 환경에서는 불필요)
-
k3s 설치
curl -sfL https://get.k3s.io | sudo sh -s - --docker
mkdir -p $HOME/.kube
sudo cp /etc/rancher/k3s/k3s.yaml $HOME/.kube/config
sudo chown $(id -un):$(id -gn) $HOME/.kube/config
kubectl version -
NFS CSI Driver 설치
helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts
helm repo update
helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs --namespace kube-system --version v4.11.0 -
NFS 서버 설치 & 디렉토리 노출
sudo apt update
sudo apt install nfs-kernel-server -y
NFS_SHARE_PATH=/data001/share/eva-agent
sudo mkdir -p ${NFS_SHARE_PATH}
# EVA Agent / vLLM 캐시 디렉토리 생성
# NFS 서버에서 소유권/권한 설정
sudo mkdir -p ${NFS_SHARE_PATH}/agent-cache ${NFS_SHARE_PATH}/vllm-cache
sudo chown -R 10001:10001 ${NFS_SHARE_PATH}
sudo chmod -R 0775 ${NFS_SHARE_PATH}
# NFS 공유는 localhost만 허용 (k3s 단일 노드 클러스터를 가정)
# 필요 시 NFS로 공유할 노드 IP 주소는 변경이 필요합니다 (다른 node의 pod에서 NFS에 접근해야 하는 경우)
echo "${NFS_SHARE_PATH} 127.0.0.1(rw,sync,no_subtree_check,root_squash,anonuid=10001,anongid=10001)" | sudo tee -a /etc/exports
sudo exportfs -ra
sudo systemctl restart nfs-kernel-server
# test
showmount -e localhost
sudo mkdir /mnt/tmp && sudo mount -t nfs -o rw,nfsvers=4 localhost:${NFS_SHARE_PATH} /mnt/tmp
sudo umount /mnt/tmp
-
Helm 저장소 등록 및 업데이트
필요한 오픈소스 레포지토리를 등록한 뒤 최신 상태로 업데이트합니다. EVA Agent를 설치할 namespace도 미리 생성합니다.
# 1. 각 레포지토리 추가
helm repo add qdrant https://qdrant.github.io/qdrant-helm
helm repo add eva-agent https://mellerikat.github.io/eva-agent
# 2. 최신 정보 업데이트
helm repo update
# 3. EVA Agent 설치용 namespace/service account 생성
kubectl create namespace eva-agent
kubectl create serviceaccount sa-eva-agent -n eva-agent
1단계: eva-agent-init 설치
이 패키지는 이후 설치할 Qdrant와 vLLM이 데이터를 저장할 수 있도록 공통 Storage Class를 미리 정의하는 단계입니다.
- 패키지 역할:
eva-agent-vllm및eva-agent-qdrant가 데이터를 안전하게 보관할 수 있도록 전용 스토리지 클래스를 구성합니다.- 따라서 반드시 다른 패키지들보다 가장 먼저 설치되어야 합니다.
설정 파일(values) 다운로드 (eva-agent-init)
위의 설정 파일을 GitHub 저장소에서 다운로드합니다. 사용하는 환경에 맞는 파일을 선택하세요.
EVA Agent의 버전(image tag)별로 values 템플릿이 정리되어 있습니다. Helm 차트 버전과 이미지 태그는 서로 다를 수 있습니다.
# Example: download k3s values
RELEASE_VERSION="2.7.0"
BASE_URL="https://raw.githubusercontent.com/mellerikat/eva-agent/chartmuseum/release/2.7.0"
mkdir -p eva-agent-init
curl -L \
"$BASE_URL/eva-agent-init/values-k3s.yaml" \
-o eva-agent-init/values-k3s.yaml
k3s + NFS를 사용하는 경우 values-k3s.yaml의 share 디렉토리는 NFS 서버의 마운트 디렉토리와 반드시 동일해야 합니다 (예: {NFS_SHARE_PATH}).
모델 캐시는 수십 GB 이상이 필요할 수 있으니, 충분한 용량의 디스크 경로를 NFS 마운트로 사용하세요. 가능하면 데이터 디스크를 마운트한 경로를 NFS 공유 경로로 쓰는 것을 권장합니다.
# (Optional) k3s + NFS: set share path to your NFS mount directory
NFS_SHARE_PATH="/data001/share/eva-agent"
# Update storageClass.fileSystem.parameters.share
sed -i "s|^[[:space:]]*share:.*| share: $NFS_SHARE_PATH|" eva-agent-init/values-k3s.yaml
# Example: install for k3s environment
helm install eva-agent-init eva-agent/eva-agent-init \
--version=1.0.0 \
-n eva-agent \
-f eva-agent-init/values-k3s.yaml
2단계: eva-agent-qdrant values 설정
벡터 데이터를 저장할 Qdrant를 설치합니다.
- values 템플릿: GitHub 저장소에서 필요한 템플릿을 확인하세요.
- 상세 values 설명: Qdrant Helm 차트의 세부 파라미터는 Artifact Hub Qdrant 페이지에서 확인할 수 있습니다.
💡 참고:
eva-agent-init에서 정의한 Storage Class를 사용하여 PVC/PV를 생성합니다. 한 번 생성된 PV는 재설치 시에도 유지되지만, 완전히 삭제하려면kubectl delete로 수동 정리해야 합니다.
사용자 환경에 맞게 설정값 업데이트
| Category | Name | Description | 값 |
|---|---|---|---|
| 일반 | nameOverride | 차트 name override | eva-agent-qdrant |
| 일반 | fullnameOverride | 리소스 전체 이름 override | "" |
| 서비스계정 | serviceAccount.create | ServiceAccount 생성 여부 | false |
| 서비스계정 | serviceAccount.name | ServiceAccount 이름 | sa-eva-agent |
| 이미지 | image.pullPolicy | 이미지 pull 정책 | Always |
| 스토리지 | persistence.accessModes | PVC 접근 모드 | ["ReadWriteOnce"] |
| 스토리지 | persistence.size | Qdrant에 할당할 PVC 용량 | 10Gi |
| 스토리지 | persistence.annotations | PVC/PV 관련 annotation (필요 시 추가) | {} |
| 스토리지 | persistence.storageVolumeName | (환경 구성에 따라) 사용할 PV/볼륨 식별용 이름 | eva-agent-qdrant-storage |
| 스토리지 | persistence.storageClassName | StorageClass 이름 | eva-agent-sc-bs |
| 스냅샷 | snapshotPersistence.enabled | 스냅샷 전용 PVC 영구 저장 사용 여부 | true |
| 스냅샷 | snapshotPersistence.accessModes | 스냅샷 PVC 접근 모드 | ["ReadWriteOnce"] |
| 스냅샷 | snapshotPersistence.size | 스냅샷 PVC 용량 | 10Gi |
| 스냅샷 | snapshotPersistence.annotations | 스냅샷 PVC/PV annotation | {} |
| 스냅샷 | snapshotPersistence.snapshotsVolumeName | 스냅샷 스토리지 PV/볼륨 식별 이름 | eva-agent-qdrant-snapshots |
| 스냅샷 | snapshotPersistence.storageClassName | 스냅샷 PVC용 StorageClass 이름 | eva-agent-sc-bs |
| 스냅샷 | snapshotRestoration.enabled | 외부 복원 소스 PVC 마운트용 선택 고급 설정(기본 주석 처리) | false (commented) |
| 스냅샷 | snapshotRestoration.pvcName | 외부 복원 소스 PVC 이름(선택, 기본 주석 처리) | qdrant-snapshot-restore-pvc |
| 스냅샷 | snapshotRestoration.mountPath | 외부 복원 소스 마운트 경로(선택, 기본 주석 처리) | /qdrant/snapshot-restoration |
| 스냅샷 | snapshotRestoration.snapshots | 복원 대상 스냅샷 파일 목록(선택, 기본 주석 처리) | [] |
| 스케줄링 | nodeSelector | 특정 노드에만 스케줄링되도록 노드 라벨 선택자 | |
설정 파일 다운로드 (eva-agent-qdrant)
Qdrant에 적용할 values와 post-renderer 플러그인 템플릿을 다운로드합니다.
RELEASE_VERSION="2.7.0"
BASE_URL="https://raw.githubusercontent.com/mellerikat/eva-agent/chartmuseum/release/2.7.0"
# Prepare directories
mkdir -p eva-agent eva-agent-init eva-agent-qdrant eva-agent-vllm \
plugin/eva-agent-qdrant
# Qdrant values & plugin
curl -L "$BASE_URL/eva-agent-qdrant/values.yaml" -o eva-agent-qdrant/values.yaml
curl -L "$BASE_URL/eva-agent-qdrant/values-aws.yaml" -o eva-agent-qdrant/values-aws.yaml
curl -L "$BASE_URL/eva-agent-qdrant/values-ncp.yaml" -o eva-agent-qdrant/values-ncp.yaml
curl -L "$BASE_URL/plugins/eva-agent-qdrant/post-renderer.sh" -o plugin/eva-agent-qdrant/post-renderer.sh
curl -L "$BASE_URL/plugins/eva-agent-qdrant/plugin.yaml" -o plugin/eva-agent-qdrant/plugin.yaml
Qdrant 복원 관련 values 설명
이 가이드는 복원 절차를 다루지 않습니다. 운영 시 참고할 수 있도록 주요 values의 의미만 정리했습니다.
snapshotPersistence.enabled/qdrant/snapshots를 PVC에 영구 보관하려면true를 유지합니다.
snapshotRestoration.enabled- 외부 PVC를 복원 소스 경로로 마운트할 때 사용하는 값입니다.
snapshotRestoration.pvcNamesnapshotRestoration.enabled=true일 때 사용할 외부 PVC 이름입니다.
snapshotRestoration.mountPath- 외부 복원 소스 파일의 Pod 마운트 경로입니다.
args- 차트 기본 시작 명령
["./config/initialize.sh"]를 유지합니다.
- 차트 기본 시작 명령
Qdrant와 vLLM 설치는 아래 스크립트 실행 단계에서 함께 진행합니다.
3단계: eva-agent-vllm values 설정
모델 추론 서버 vLLM을 설치합니다. (Agent 이미지 버전 2.2-a2.0 이상 필요)
- values 템플릿: GitHub 저장소에서 확인할 수 있습니다.
- 차트 소스: 본 가이드는
eva-agentHelm 저장소의 커스텀 차트eva-agent/eva-agent-vllm을 설치합니다. - 상세 values 설명: 먼저
eva-agent-vllm디렉토리의 release 템플릿을 기준으로 값을 설정한 뒤, Artifact Hub vLLM-stack은 엔진 레벨 옵션 확인용으로 참고하세요. - 핵심 설정: PVC/PV의 원활한 동적 할당을 위해
nodeSelector설정이 올바른지 반드시 확인하세요.
💡 참고:
eva-agent-init에서 정의한 Storage Class를 사용하여 PVC/PV를 생성합니다. 한 번 생성된 PV는 재설치 시에도 유지되지만, 완전히 삭제하려면kubectl delete로 수동 정리해야 합니다.
사용자 환경에 맞게 설정값 업데이트
아래 필터에서 배포 환경 / 서비스 구분 / 세부 항목을 선택하면 해당 설정값만 표시됩니다.
| Category | Name | Description | 값 | 비고 |
|---|---|---|---|---|
| Router | routerSpec.enableRouter | Model Router 사용 여부 | true | 값 설정 가이드 참고 |
| Router | routerSpec.routingLogic | 라우팅 방식(roundrobin 또는 session; session은 키 고정, 키 없으면 최저 QPS) | "roundrobin" | |
| Router | routerSpec.serviceDiscovery | 라우팅 대상 discovery 방식 | "static" | 값 설정 가이드 참고 |
| Router | routerSpec.staticBackends | static backend endpoint 목록 | "http://eva-agent-vllm-qwen3-vl-8b-fp8-engine-service.eva-agent.svc.cluster.local, http://external.vllm.ip:port" | 값 설정 가이드 참고 |
| Router | routerSpec.staticModels | static backend 모델명 매핑 | "qwen3-vl-8b-instruct-fp8,Exaone4.0" | 값 설정 가이드 참고 |
| Router | routerSpec.serviceType | Router Service 타입 | "ClusterIP" | 외부 미노출 |
| Router | routerSpec.servicePort | Router Service 포트 | 80 | |
| Router | routerSpec.containerPort | Router 컨테이너 포트 | 8000 |
값 설정 가이드 펼치기
-
routerSpec.enableRouter
- 기본값은 항상 사용입니다. 운영 환경에서는 특별한 이유가 없으면
true로 두는 것을 권장합니다. - Router는 새 엔진을 띄우지 않고, 이미 실행 중인 vLLM 엔드포인트로만 라우팅합니다.
- 이 엔드포인트는 같은 Helm 설치로 동시에 배포되는 엔진 파드일 수도 있고, 다른 클러스터/다른 배포일 수도 있습니다.
- Kubernetes 파드가 아니어도 됩니다. 도커 컨테이너, bare‑metal 프로세스, Python 서버 등 HTTP로 접근 가능한 vLLM endpoint면 모두 연결 가능합니다.
- 여러 모델을 한 노드에 함께 띄우는 구성이거나, 엔진이 분산되어 있는 구성이라면 Router는 사실상 필수입니다.
- 요약하면 Router는 “어디에 있든지 접근 가능한 vLLM 엔드포인트”를 묶어 단일 진입점으로 분산하는 reverse proxy입니다.
- 기본값은 항상 사용입니다. 운영 환경에서는 특별한 이유가 없으면
-
routerSpec.serviceDiscovery
- 설정 가능한 값은
k8s,static두 가지입니다. - 권장값은
static입니다. 같은 클러스터 내부만 쓰더라도static을 사용할 수 있고, 운영에서 예측 가능한 구성이 됩니다. - vLLM 엔진은 Headless가 아닌 Service(ClusterIP/NodePort) 로 노출하도록 구성합니다.
따라서 내부 DNS가 대표 진입점 역할을 하므로, 같은 클러스터 내부에서도static으로 endpoint 추적이 가능합니다.
운영 관점에서는k8s와 큰 차이는 없고, 선택은 관리 방식의 차이입니다. k8s는 엔드포인트가 자주 바뀌는 환경(자동 스케일, 잦은 롤링)에서 유리합니다. 자동으로 Endpoints를 따라갑니다.static은 라우팅 대상이 명확히 고정되어 있거나, 외부 엔드포인트를 포함해야 할 때 적합합니다. 변경 시에는 리스트를 직접 갱신해야 합니다.
- 설정 가능한 값은
-
routerSpec.routingLogic
roundrobin: 리스트 순서대로 균등 분배합니다.session: 세션 키 기준으로 고정 라우팅하며, 키가 없으면 최저 QPS 엔진을 선택합니다.- 리소스 기반 라우팅은 아닙니다. 가중 분배가 필요하면
staticBackends에 대상 URL을 반복합니다(예: 6:1).
-
routerSpec.staticBackends
- 콤마(,)로 구분된 한 줄 문자열입니다.
- 같은 클러스터라면 Headless 서비스는 사용하지 마세요. ClusterIP/NodePort 서비스가 진입점입니다.
- 서비스 DNS는 모델 이름으로 구성합니다:
http://eva-agent-vllm-<servingEngineSpec.modelSpec[].name>-engine-service.<namespace>.svc.cluster.local- 예시(모델 이름
qwen3-vl-8b-fp8):http://eva-agent-vllm-qwen3-vl-8b-fp8-engine-service.eva-agent.svc.cluster.local
- namespace는 반드시 포함하세요. Router URL 검증 로직에서 점(
.) 없는 호스트명을 invalid로 거절합니다. - 외부 엔드포인트 예시:
http://203.0.113.10/v1
-
routerSpec.staticModels
staticBackends순서와 동일하게 콤마(,)로 나열.- 모델 이름은
servingEngineSpec.modelSpec[].vllmConfig.extraArgs의--served-model-name값과 반드시 같아야 합니다. - 확실하지 않다면 실행 중인 엔드포인트에서
curl <endpoint>/v1/models로 확인하세요 (파드/컨테이너/외부 서버 모두 가능).- 응답의
id필드가 모델명입니다. 예:{"object":"list","data":[{"id":"qwen3-vl-8b-instruct-fp8"...}]}.
- 응답의
-
servingEngineSpec.modelSpec[].name
- 이 값이
routerSpec.staticBackends서비스 DNS 생성에 사용됩니다. - 같은 모델이라면 변경하지 않는 것을 추천합니다. (다른 모델이면 Hugging Face repo가 달라지므로 모델명도 달라져야 합니다.)
- 이 값이
-
servingEngineSpec.modelSpec[].modelURL
- 서빙할 모델의 Hugging Face repo 경로를 입력합니다. (예:
Qwen/Qwen3-VL-8B-Instruct-FP8)
- 서빙할 모델의 Hugging Face repo 경로를 입력합니다. (예:
-
servingEngineSpec.modelSpec[].vllmConfig.tensorParallelSize
- 의미: 하나의 모델(엔진 파드)이 사용할 GPU 개수입니다.
- 오버헤드: TP가 커질수록 GPU 간 통신 비용이 증가합니다. 메모리/처리량을 만족하는 최소 값으로 설정 하세요.
- 제약:
tensorParallelSize는 모델의 attention head 수(num_attention_heads)를 나눌 수 있어야 합니다. - 자세한 구성은 서버별 배포 가이드를 참고하세요.
-
servingEngineSpec.modelSpec[].vllmConfig.gpuMemoryUtilization
- GPU 메모리 사용 상한을 제어합니다.
1.0으로 설정하지 마세요. KV Cache에는 prefix/multi‑modal 입력의 임베딩 메모리가 포함되지 않으므로 여유 공간이 필요합니다.- GPU를 독점 사용할 때는 높게(기본
0.9), EVA Vision과 공유할 때는 낮게 설정합니다. - 24GB GPU라면
0.8~0.85범위로 시작하는 것을 권장합니다. - 구체 예시는 서버별 배포 가이드를 참고하세요.
-
servingEngineSpec.modelSpec[].vllmConfig.extraArgs
--served-model-name은staticModels와 동일해야 합니다.kv-cache-dtype은 GPU 아키텍처에 따라 다르며, Ada 이전은auto로 설정합니다.
-
servingEngineSpec.modelSpec[].requestCPU
- CPU는 GPU와 별개입니다. 토크나이저/워커/I/O를 감당할 만큼 확보하세요.
- EVA Vision과 같은 노드에서 공존한다면 EVA Vision 파드의 CPU 여유도 남겨야 합니다.
-
servingEngineSpec.modelSpec[].requestMemory
- 시스템 RAM 용량입니다(VRAM 아님). 낮으면 GPU가 충분해도 OOM이 날 수 있습니다.
- KV Cache 압박이 크면
maxModelLen은 12K로 유지하고 메모리를 늘리거나 GPU/TP를 확장하세요.
-
servingEngineSpec.modelSpec[].requestGPU
- 중요:
requestGPU를 지정하면 Kubernetes에서 해당 GPU를 독점적으로 할당합니다. - GPU 공유가 필요하면
requestGPU를 주석 처리하고gpuMemoryUtilization/maxModelLen으로 조절하세요. - EVA Vision이 GPU의 일부만 사용한다면, MIG/time‑slicing이 활성화된 경우에만 fractional GPU로 여러 엔진을 띄울 수 있습니다. (비활성화 시에는 정수 GPU만 가능)
- 독점으로 사용할 때는
requestGPU를 정수로 두고gpuMemoryUtilization로 조정합니다.0.9같은 값은requestGPU에 쓸 수 없습니다(MIG/time‑slicing 제외). - 구체적인 서버별 설정은 서버별 배포 가이드를 참고하세요.
- 중요:
서버별 배포 가이드 펼치기
- EVA가 실제로 배포되는 서버 기준으로 설정값을 정리합니다.
- 아래 케이스들은 모두
routerSpec.staticBackends와routerSpec.staticModels의 순서가 일치해야 합니다.
- RTX A6000 x1 (48GB)
- L40s x1 (48GB)
- RTX 4090 x3 (24GB)
- RTX PRO 5000 x3 (48GB)
- 추가 케이스
- 환경
- EVA Vision과 GPU 공유
- 외부 vLLM pod 1개 추가 연결 (Router에서 Qwen3‑VL 8B & Exaone 4.0 라우팅)
- 필수 설정값
routerSpec.enableRouter: truerouterSpec.serviceDiscovery: "static"routerSpec.staticBackends: 내부 엔진 + 외부 엔진 URL을 콤마로 연결- 내부 엔진 예시:
http://eva-agent-vllm-qwen3-vl-8b-fp8-engine-service.<namespace>.svc.cluster.local - 외부 엔진 예시:
http://203.0.113.10/v1
- 내부 엔진 예시:
routerSpec.staticModels:qwen3-vl-8b-instruct-fp8,Exaone4.0servingEngineSpec.modelSpec[].name: qwen3-vl-8b-fp8servingEngineSpec.modelSpec[].vllmConfig.extraArgs:--served-model-name qwen3-vl-8b-instruct-fp8,--kv-cache-dtype autoservingEngineSpec.modelSpec[].vllmConfig.tensorParallelSize: 1servingEngineSpec.modelSpec[].requestGPU: 주석 처리 (EVA Vision과 GPU 공유)servingEngineSpec.modelSpec[].vllmConfig.gpuMemoryUtilization: 0.7(EVA Vision 10GB 공유 기준)servingEngineSpec.modelSpec[].vllmConfig.maxModelLen: 12288
- 체크 포인트
- 외부 엔진은
/v1/models의id값이Exaone4.0인지 확인 routerSpec.staticBackends는 점(.) 포함 URL만 허용 (서비스/도메인 명시 필수)- 계산 기준: 48GB - 10GB(EVA Vision) = 38GB → 38/48 ≈ 0.79, 운영 여유 확보를 위해
0.7로 설정 - Ampere GPU는
--kv-cache-dtype auto사용
- 외부 엔진은
- 환경
- EVA Vision과 GPU 공유
- 외부 vLLM pod 1개 추가 연결 (Router에서 Qwen3‑VL 8B & Exaone 4.0 라우팅)
- 필수 설정값
routerSpec.enableRouter: truerouterSpec.serviceDiscovery: "static"routerSpec.staticBackends: 내부 엔진 + 외부 엔진 URL을 콤마로 연결- 내부 엔진 예시:
http://eva-agent-vllm-qwen3-vl-8b-fp8-engine-service.<namespace>.svc.cluster.local - 외부 엔진 예시:
http://203.0.113.10/v1
- 내부 엔진 예시:
routerSpec.staticModels:qwen3-vl-8b-instruct-fp8,Exaone4.0servingEngineSpec.modelSpec[].name: qwen3-vl-8b-fp8servingEngineSpec.modelSpec[].vllmConfig.extraArgs:--served-model-name qwen3-vl-8b-instruct-fp8,--kv-cache-dtype fp8servingEngineSpec.modelSpec[].vllmConfig.tensorParallelSize: 1servingEngineSpec.modelSpec[].requestGPU: 주석 처리 (EVA Vision과 GPU 공유)servingEngineSpec.modelSpec[].vllmConfig.gpuMemoryUtilization: 0.7(EVA Vision 10GB 공유 기준)servingEngineSpec.modelSpec[].vllmConfig.maxModelLen: 12288
- 체크 포인트
- 외부 엔진은
/v1/models의id값이Exaone4.0인지 확인 routerSpec.staticBackends는 점(.) 포함 URL만 허용 (서비스/도메인 명시 필수)- 계산 기준: 48GB - 10GB(EVA Vision) = 38GB → 38/48 ≈ 0.79, 운영 여유 확보를 위해
0.7로 설정 - Ada GPU는
--kv-cache-dtype fp8사용 가능
- 외부 엔진은
- 환경
- EVA Vision은 GPU 1장 독점 사용
- vLLM은 GPU 2장 독점 사용 (외부 vLLM 백엔드 없음)
- Router는 단일 모델(Qwen3‑VL 8B)이라도 운영 편의상 유지
- 필수 설정값
routerSpec.enableRouter: truerouterSpec.serviceDiscovery: "static"routerSpec.staticBackends: 내부 엔진만 등록- 예시:
http://eva-agent-vllm-qwen3-vl-8b-fp8-engine-service.<namespace>.svc.cluster.local
- 예시:
routerSpec.staticModels:qwen3-vl-8b-instruct-fp8servingEngineSpec.modelSpec[].name: qwen3-vl-8b-fp8servingEngineSpec.modelSpec[].vllmConfig.extraArgs:--served-model-name qwen3-vl-8b-instruct-fp8,--kv-cache-dtype fp8servingEngineSpec.modelSpec[].vllmConfig.tensorParallelSize: 1servingEngineSpec.modelSpec[].requestGPU: 1(독점)servingEngineSpec.modelSpec[].replicaCount: 2(엔진 파드 2개, GPU 1장씩)servingEngineSpec.modelSpec[].vllmConfig.gpuMemoryUtilization: 0.85(24GB, 독점)servingEngineSpec.modelSpec[].vllmConfig.maxModelLen: 12288
- 체크 포인트
routerSpec.staticBackends는 점(.) 포함 URL만 허용- vLLM 로그 기준 8‑bit KV Cache에서 12K 요청 약 7개 동시 처리 가능 → 1GPU 엔진 2개가 동시성에 유리
- 단일 백엔드에서 Router 오버헤드를 줄이고 싶으면 비활성화할 수 있지만, 확장성을 위해 유지하는 것을 권장
- 차트 가능 여부
- vLLM production stack은
servingEngineSpec.modelSpec로 다중 엔진을 만들고, 항목별 Deployment가 생성되어 엔진별 패치가 가능합니다.
- vLLM production stack은
- 구성 A — 독점 2 + 1
- EVA Vision은 GPU 1장을 독점 사용.
- vLLM은 GPU 2장을 독점 사용 (외부 백엔드 없음, Qwen3‑VL만 사용).
- Router는 안정적인 진입점을 위해 유지.
- 필수 설정값 (vLLM)
routerSpec.enableRouter: truerouterSpec.serviceDiscovery: "static"routerSpec.staticBackends: 내부 엔진만 등록- 예시:
http://eva-agent-vllm-qwen3-vl-8b-fp8-engine-service.<namespace>.svc.cluster.local
- 예시:
routerSpec.staticModels:qwen3-vl-8b-instruct-fp8servingEngineSpec.modelSpec[].vllmConfig.extraArgs:--served-model-name qwen3-vl-8b-instruct-fp8,--kv-cache-dtype fp8tensorParallelSize: 1,requestGPU: 1,replicaCount: 2servingEngineSpec.modelSpec[].vllmConfig.gpuMemoryUtilization: 0.9(독점)servingEngineSpec.modelSpec[].vllmConfig.maxModelLen: 12288
- 구성 B — 2 GPU + MIG 분할 (2.5 + 0.5)
- 2장은 일반 GPU로 vLLM, 남은 1장은 MIG로 나눠 vLLM + EVA Vision 사용.
- 단일 release 권장:
modelSpec을 GPU/MIG로 분리하고 Router가 둘 다 바라보게 구성.- Router 분배: 6:1 (독점:공유)로 맞추려면
staticBackends에 독점 엔진을 6번 반복합니다.- 예시:
routerSpec.routingLogic: "roundrobin"routerSpec.staticBackends:독점6개 +공유1개routerSpec.staticModels:qwen3-vl-8b-instruct-fp8동일 반복
- 예시:
- 예시 values:
routerSpec:
enableRouter: true
serviceDiscovery: "static"
staticBackends: "http://eva-agent-vllm-qwen3-vl-8b-fp8-gpu-engine-service.<ns>.svc.cluster.local,http://eva-agent-vllm-qwen3-vl-8b-fp8-gpu-engine-service.<ns>.svc.cluster.local,http://eva-agent-vllm-qwen3-vl-8b-fp8-gpu-engine-service.<ns>.svc.cluster.local,http://eva-agent-vllm-qwen3-vl-8b-fp8-gpu-engine-service.<ns>.svc.cluster.local,http://eva-agent-vllm-qwen3-vl-8b-fp8-gpu-engine-service.<ns>.svc.cluster.local,http://eva-agent-vllm-qwen3-vl-8b-fp8-gpu-engine-service.<ns>.svc.cluster.local,http://eva-agent-vllm-qwen3-vl-8b-fp8-mig-engine-service.<ns>.svc.cluster.local"
staticModels: "qwen3-vl-8b-instruct-fp8,qwen3-vl-8b-instruct-fp8,qwen3-vl-8b-instruct-fp8,qwen3-vl-8b-instruct-fp8,qwen3-vl-8b-instruct-fp8,qwen3-vl-8b-instruct-fp8,qwen3-vl-8b-instruct-fp8"
servingEngineSpec:
modelSpec:
- name: "qwen3-vl-8b-fp8-gpu"
replicaCount: 2
requestGPU: 1
- name: "qwen3-vl-8b-fp8-mig"
replicaCount: 1
requestGPU: 1 # placeholder; MIG로 패치
- Router 분배: 6:1 (독점:공유)로 맞추려면
- MIG 패치(post‑renderer): MIG 엔진 Deployment만
nvidia.com/gpu→nvidia.com/mig-*로 교체.- 하나의 파드에서
nvidia.com/gpu와nvidia.com/mig-*를 동시에 요청하면 안 됩니다. MIG 엔진에서는 GPU 리소스를 제거하세요. - 예시(48GB 기준, 실제 프로필명으로 교체):
apiVersion: apps/v1
kind: Deployment
metadata:
name: eva-agent-vllm-qwen3-vl-8b-fp8-mig-deployment-vllm
spec:
template:
spec:
containers:
- name: vllm-container
resources:
limits:
nvidia.com/mig-2g.24gb: 1
requests:
nvidia.com/mig-2g.24gb: 1
- 하나의 파드에서
- 단일 release에서 패치가 어려우면
- Release A(일반 GPU): router 활성,
replicaCount: 2,requestGPU: 1 - Release B(MIG): router 비활성,
replicaCount: 1, post‑renderer로nvidia.com/mig-*패치
- Release A(일반 GPU): router 활성,
- 구성 C — k3s VM 분리 + GPU passthrough
- 호스트를 VM 2대로 분리하고 GPU passthrough로 2장/1장을 각각 할당합니다.
- 각 VM에 k3s 노드를 구성하면 스케줄러가 물리적으로 분리된 GPU 풀로 인식합니다.
- VM‑A (GPU 2장, vLLM 독점)
requestGPU: 1,replicaCount: 2(엔진 2개, GPU 1장씩)
- VM‑B (GPU 1장, EVA Vision + 공유 vLLM)
- EVA Vision 배치 노드
- vLLM은
requestGPU주석 처리 후gpuMemoryUtilization조정
- Router 분배: 6:1 (VM‑A 독점 : VM‑B 공유)
routerSpec.routingLogic: "roundrobin"routerSpec.staticBackends:VM‑A6개 +VM‑B1개
- 체크 포인트
- 사용 가능한 MIG 프로필 확인:
kubectl describe node | grep nvidia.com/mig - MIG 프로필이 없으면 구성 A로 운영
- 사용 가능한 MIG 프로필 확인:
- 여기에 다른 서버 구성(예: L40s x1, 다중 GPU 등)을 추가합니다.
설정 파일 다운로드 (eva-agent-vllm)
vLLM에 적용할 values 템플릿을 다운로드합니다.
아래 템플릿 중 공통 values.yaml과 values-k3s.yaml 파일은 Nvidia A6000 GPU 1장인 서버를 기준으로 하고, values-aws.yaml 파일은 Nvidia L40s GPU 한 장인 서버가 기준입니다.
vLLM 관련 설정값은 위 표를 참고해 GPU 서버 사양에 맞게 변경해야 합니다.
RELEASE_VERSION="2.7.0"
BASE_URL="https://raw.githubusercontent.com/mellerikat/eva-agent/chartmuseum/release/2.7.0"
# vLLM values
curl -L "$BASE_URL/eva-agent-vllm/values.yaml" -o eva-agent-vllm/values.yaml
curl -L "$BASE_URL/eva-agent-vllm/values-k3s.yaml" -o eva-agent-vllm/values-k3s.yaml
curl -L "$BASE_URL/eva-agent-vllm/values-aws.yaml" -o eva-agent-vllm/values-aws.yaml
curl -L "$BASE_URL/eva-agent-vllm/values-ncp.yaml" -o eva-agent-vllm/values-ncp.yaml
4단계: Qdrant, vLLM 설치
Qdrant와 vLLM의 values를 배포 환경에 맞게 수정한 뒤, 스크립트로 설치합니다.
필요에 따라 아래 옵션을 추가로 설정할 수 있습니다.
--namespace <ns>: 설치할 namespace (기본:eva-agent)--release <ver>: release 버전 (기본:2.7.0)--base-dir <dir>: values/plugin 디렉토리 기준 경로 (기본: 현재 디렉토리)--components <target>: 설치 대상,both,qdrant,vllm중 하나 (기본:both)--qdrant-chart-version <ver>: Qdrant chart 버전 (기본:1.16.3)--vllm-chart-version <ver>: vLLM chart 버전 (기본:0.1.10)--qdrant-values <file>: Qdrant values 추가 파일 (여러 번 사용 가능)--vllm-values <file>: vLLM values 추가 파일 (여러 번 사용 가능)
전체 옵션과 기본값은 ./install_eva_agent_dependencies.sh --help에서 확 인할 수 있습니다.
한쪽만 설치하려면 --components qdrant 또는 --components vllm을 사용하세요.
# 설치 스크립트 다운로드
curl -L "https://raw.githubusercontent.com/mellerikat/eva-agent/chartmuseum/install_eva_agent_dependencies.sh" \
-o install_eva_agent_dependencies.sh
chmod +x install_eva_agent_dependencies.sh
# values 수정 후 실행 (Qdrant는 post-renderer 사용, vLLM은 커스텀 차트를 직접 사용)
# k3s 예시
./install_eva_agent_dependencies.sh \
--qdrant-values eva-agent-qdrant/values-k3s.yaml \
--vllm-values eva-agent-vllm/values-k3s.yaml
# AWS 예시
./install_eva_agent_dependencies.sh \
--qdrant-values eva-agent-qdrant/values-aws.yaml \
--vllm-values eva-agent-vllm/values-aws.yaml
# NCP 예시
./install_eva_agent_dependencies.sh \
--qdrant-values eva-agent-qdrant/values-ncp.yaml \
--vllm-values eva-agent-vllm/values-ncp.yaml