10.5. 원격 모델 제어¶
Backend.AI GO를 사용하면 헤드 노드에서 원격 머신에 직접 접근하지 않고도 연결된 원격 노드의 모델을 로드 및 언로드할 수 있습니다. 이것으로 분산 추론 워크플로우가 완성됩니다. 노드를 연결하고, 노드 간에 추론 요청을 라우팅하며, 이제 각 노드에서 실행 중인 모델을 단일 인터페이스에서 관리할 수 있습니다.
개요¶
원격 노드가 등록되면 헤드 노드는 해당 노드의 기본 URL과 API 키를 저장합니다. 원격 모델 제어는 이 정보를 사용하여 사용자를 대신해 원격 노드의 Management API로 모델 관리 명령을 전송합니다.
다음 작업이 지원됩니다:
- 모델 로드 — 원격 노드에 모델 서빙을 시작하도록 지시
- 모델 언로드 — 원격 노드에서 실행 중인 모델 중지
- 로드된 모델 목록 — 원격 노드에서 현재 활성화된 모델 조회
API 레퍼런스¶
세 가지 작업 모두 Tauri IPC 명령(데스크탑 앱)과 REST API 엔드포인트(헤드리스 모드)로 사용할 수 있습니다.
원격 노드에 모델 로드¶
Tauri IPC: load_model_on_remote_node
REST: POST /api/v1/nodes/{fingerprint}/models/load
요청 본문:
{
"modelId": "llama-3-8b-q4",
"modelPath": "/path/to/model.gguf",
"contextLength": 4096,
"gpuLayers": -1
}
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
modelId | string | 예 | 로드할 모델 식별자 |
modelPath | string | 아니요 | 원격 노드의 모델 파일 절대 경로 |
contextLength | number | 아니요 | 기본 컨텍스트 길이 재정의 |
gpuLayers | number | 아니요 | GPU 레이어 수 (-1은 전체) |
응답:
실패 시 success는 false이며 error 필드에 문제가 설명됩니다.
원격 노드에서 모델 언로드¶
Tauri IPC: unload_model_on_remote_node
REST: POST /api/v1/nodes/{fingerprint}/models/unload
요청 본문:
응답:
원격 노드의 모델 목록 조회¶
Tauri IPC: get_remote_node_models
REST: GET /api/v1/nodes/{fingerprint}/models
응답:
{
"data": [
{
"id": "llama-3-8b-q4",
"path": "/models/llama-3-8b-q4.gguf",
"endpoint": "http://127.0.0.1:8081",
"healthy": true
}
]
}
실시간 업데이트¶
원격 노드에서 모델이 성공적으로 로드되거나 언로드되면 헤드 노드는 distributed-pool-changed 이벤트를 전송합니다. 프론트엔드 nodeStore는 이 이벤트를 구독하여 자동으로 다음을 수행합니다:
- 영향을 받은 노드의 원격 모델 목록 새로고침 (
fetchRemoteModels). - 전체 분산 풀 상태 새로고침 (
getDistributedPoolStatus).
이를 통해 수동으로 페이지를 새로고침하지 않아도 UI가 동기화 상태를 유지합니다.
헤드리스 모드에서는 동일한 이벤트가 GET /api/v1/events의 SSE(Server-Sent Events) 스트림을 통해 브로드캐스트됩니다.
타임아웃¶
대용량 모델을 고려하여 작업에는 여유 있는 타임아웃이 적용됩니다:
| 작업 | 타임아웃 |
|---|---|
| 모델 로드 | 600초 (10분) |
| 모델 언로드 | 60초 |
| 모델 목록 조회 | 30초 |
타임아웃이 발생하면 응답에 "success": false와 함께 타임아웃 시간을 나타내는 오류 메시지가 포함됩니다.
오류 처리¶
| 조건 | 동작 |
|---|---|
| 노드 핑거프린트가 등록되지 않음 | 404 Not Found 반환 |
| 원격 노드에 연결할 수 없음 (연결 거부) | 연결 메시지와 함께 오류 반환 |
| 원격 노드 요청 타임아웃 | 타임아웃 시간과 함께 오류 반환 |
| 원격 노드가 2xx가 아닌 응답 반환 | 원격 오류 본문을 파싱하여 반환 |
| 빈 모델 ID 또는 경로 탐색이 포함된 모델 ID | 요청 전에 거부 |
모델 ID는 네트워크 요청 전에 검증됩니다. 빈 모델 ID와 .. 시퀀스가 포함된 ID는 URL 경로 조작을 방지하기 위해 거부됩니다.
프론트엔드 스토어¶
useNodeStore Zustand 스토어는 원격 모델 제어를 위한 다음 셀렉터와 액션을 제공합니다:
| 내보내기 | 타입 | 설명 |
|---|---|---|
useRemoteModels(fingerprint) | 셀렉터 | 특정 노드에 대한 캐시된 모델 |
useAllRemoteModels() | 셀렉터 | 핑거프린트별로 키가 지정된 모든 원격 모델 |
useIsRemoteModelOperating(fingerprint) | 셀렉터 | 로드/언로드가 진행 중인지 여부 |
loadModelOnNode(fingerprint, request) | 액션 | 원격 노드에 모델 로드 |
unloadModelOnNode(fingerprint, modelId) | 액션 | 원격 노드에서 모델 언로드 |
fetchRemoteModels(fingerprint) | 액션 | 노드의 모델 목록 새로고침 |
언로드는 낙관적 업데이트를 수행합니다. 모델은 즉시 로컬 캐시에서 제거되고, distributed-pool-changed 이벤트가 백엔드에서 전체 새로고침을 트리거합니다.
보안¶
원격 노드에 대한 모든 요청은 Authorization: Bearer <api_key> 헤더를 사용합니다. API 키는 로컬 노드 레지스트리에 안전하게 저장되며 로그나 UI에 노출되지 않습니다. 모델 ID는 경로 인젝션을 방지하기 위해 URL에서 퍼센트 인코딩됩니다.
파이프라인 스테이지 워커 제어¶
다중 노드 파이프라인 병렬 서빙(에픽 #3413)을 위해 헤드 노드는 동일한 인증된 피어 채널을 통해 등록된 서브 노드에서 로컬 mlxcel-server 스테이지 프로세스를 시작, 중지, 폴링할 수 있습니다. 서브 노드는 클러스터 TOML을 로컬에 기록하고 스테이지를 시작합니다. 헤드는 코디네이터가 연결하기 전에 트랜스포트 포트 준비 상태를 폴링합니다.
서브 노드에서 스테이지 시작¶
Tauri IPC: spawn_stage_on_remote_node
REST: POST /api/v1/nodes/{fingerprint}/distributed/stages
요청 본문은 GO에서 생성된 clusterId, 전체 clusterToml, 서브 노드의 nodeId, #3414 빌더의 launch 매개변수, 선택적 layerRange를 포함하는 SpawnStageRequest입니다. 응답은 StageStatus입니다(아래 참조). launch의 API 키는 파일 경로만 전송되며 비밀값은 전송되지 않습니다.
서브 노드에서 스테이지 중지¶
Tauri IPC: stop_stage_on_remote_node
REST: DELETE /api/v1/nodes/{fingerprint}/distributed/stages/{cluster_id}
멱등성: 이미 종료된 스테이지를 중지하면 오류 없이 stopped: false를 반환합니다.
서브 노드의 스테이지 상태 폴링¶
Tauri IPC: get_stage_status_on_remote_node
REST: GET /api/v1/nodes/{fingerprint}/distributed/stages/{cluster_id}
서브 노드에서 해당 클러스터의 스테이지가 추적되지 않으면 404를 반환합니다. StageStatus 페이로드에는 다음이 포함됩니다:
| 필드 | 설명 |
|---|---|
clusterId | 이 스테이지가 속한 클러스터 |
nodeId | 클러스터 내 서브 노드 id |
stage | 0부터 시작하는 스테이지 인덱스 |
processState | "running" 또는 "exited" |
transportPortReady | 노드 간 트랜스포트 포트가 TCP 연결을 수락하는지 여부 |
transportAddress | 스테이지가 바인딩하는 호스트와 포트 |
layerRange | 고정된 경우 포함적 레이어 할당 [start, end] |
lastError | 마지막으로 발생한 정제된 오류, 없을 경우 생략 |
서브 노드는 이 세 가지 라우트를 POST/DELETE/GET /api/v1/distributed/stages[/{cluster_id}]에서 처리하며, 모델 제어 라우트와 동일한 ak_ 노드 키로 인증합니다.
타임아웃¶
| 작업 | 타임아웃 |
|---|---|
| 스테이지 시작 | 600초 (스테이지 로드 시 모델 가중치 읽기) |
| 스테이지 중지 | 60초 |
| 상태 폴링 | 15초 |