AI Engine Runtime 详解:AIBrix 推理引擎统一管理 Sidecar 的指标标准化、模型下载与 LoRA 动态加载实战
【免费下载链接】aibrixCost-efficient and pluggable Infrastructure components for GenAI inference项目地址: https://gitcode.com/GitHub_Trending/ai/aibrix
AI Engine Runtime(aibrix-runtime)是 AIBrix 控制平面与推理引擎 Pod 之间的统一管理边车(sidecar):它把 vLLM 等推理引擎差异化的指标、模型与适配器管理能力收敛为控制平面可稳定调用的 HTTP API。本文将从架构原理、Sidecar 注入部署、指标标准化、多源模型下载、LoRA 动态加载到完整配置与 API 参考,逐层讲透这个组件的安装与实战用法。
AI Engine Runtime 是什么
AI Engine Runtime 是一个运行在推理引擎旁边的小型 HTTP 服务,通常以同一 Pod 内的 sidecar 容器形式存在。它存在的根本原因是:不同的推理引擎(vLLM、SGLang、TRT-LLM 等)对外暴露的能力各不相同,而 AIBrix 控制平面(自动扩缩容控制器、LoRA 适配器控制器、网关等)需要一套稳定的接口来读写这些引擎。Runtime 恰好充当了这层"翻译器"。
从 设计文档 的定位来看,它为控制平面提供三大类能力:
- 指标标准化(Metric standardization):抓取引擎自身的
/metrics,在自身端口上以统一命名重新导出,让自动扩缩容器和网关只面对一种指标形状。 - 模型与适配器管理(Model and adapter management):从 HuggingFace、S3、TOS 下载模型权重,并在引擎上加载/卸载 LoRA 适配器。LoRA 动态加载 控制器正是通过它的端点完成适配器生命周期管理。
- 运行时模型生命周期(Runtime model lifecycle):一组实验性端点,供 ModelClaim 在共享 Pod 中启动、休眠、唤醒和停用引擎进程。
需要特别澄清的是:Runtime 不代理推理流量。Envoy 网关直接把请求转发给引擎容器本身,网关与 Runtime 的唯一接触点是对休眠中的 ModelClaim 引擎发起 wake 调用。因此大多数部署并不需要安装 Runtime,只有在使用动态 LoRA 加载或ModelClaim时才需要安装它。
同样值得注意的是,它与 Istio 之类的数据面 sidecar 有本质区别——数据面流量完全不会经过它,它只提供控制平面交互所需的管理能力。
工作原理
Runtime 的整体架构与数据流可以用下图概括:
其核心交互逻辑如下:
- Runtime 监听8080端口,通过
INFERENCE_ENGINE_ENDPOINT(默认http://localhost:8000)访问引擎。 - 控制平面(ModelAdapter / ModelClaim 控制器)通过
:8080的 HTTP 接口驱动 Runtime;Prometheus / 自动扩缩容器则抓取:8080/metrics。 - Runtime 内部再向引擎的
/metrics、/v1/load_lora_adapter等端点发起请求,完成指标采集与适配器操作。
控制平面如何使用 Runtime
控制器管理器有一个全局开关--enable-runtime-sidecar,它只影响 ModelAdapter(LoRA)控制器的行为:
- 开启时:当 Pod 中存在名为
aibrix-runtime的容器时,LoRA 控制器通过 8080 端口的 Runtime API 工作;否则回退到引擎自身 8000 端口的 API。 - 关闭时(默认):始终直接调用引擎 API。
ModelClaim 控制器和网关的 wake 路径则始终使用 8080 端口的 Runtime,不受该 flag 影响。
从源码看,这条分支逻辑实现在 pkg/controller/modeladapter/lora_client.go 中:useSidecar := c.runtimeConfig.EnableRuntimeSidecar && DetectRuntimeSidecar(targetPod),即"全局开关开启"且"Pod 中检测到 Runtime 容器"两个条件同时满足时才走 sidecar 路径。LoRA 相关端点路径也定义于此文件:/v1/lora_adapter/load、/v1/lora_adapter/unload、/v1/models。
引擎支持边界
两个关键事实必须牢记:
- 指标在每个抓取周期都会重新采集:Runtime 抓取引擎的 metrics 页面,应用
INFERENCE_ENGINE对应的标准化规则后提供服务。代码中虽然存在sglang和trtllm的规则集,但Runtime 只支持以INFERENCE_ENGINE=vllm启动——启动时初始化的引擎客户端会拒绝任何其他值。 - 模型管理 API(
/v1/lora_adapter/*、/v1/models)仅为 vLLM 0.6.1 及以上版本实现,其他引擎暂不支持这些端点。
安装与部署
AIBrix Runtime 可以通过基于 Webhook 的 sidecar 自动注入(推荐)或手动添加到 Deployment 清单中两种方式部署。
自动 Sidecar 注入(推荐)
最简单的启用方式是通过自动 sidecar 注入:只需在 Deployment 或 StormService 上添加注解model.aibrix.ai/sidecar-injection: "true":
apiVersion: apps/v1 kind: Deployment metadata: name: vllm-server annotations: model.aibrix.ai/sidecar-injection: "true" # Enable automatic runtime injection spec: template: spec: containers: - name: vllm image: vllm/vllm-openai:latest # Your container configuration...Webhook 会自动把aibrix-runtimesidecar 容器注入到你的 Pod 中。相关的注解与容器名常量定义在 pkg/webhook/sidecar_injection.go(SidecarInjectionAnnotation = "model.aibrix.ai/sidecar-injection",SidecarName = "aibrix-runtime")。
注入后的 Pod spec 里会出现什么
了解注入内容有助于你核对最终生成的 Pod 规格:
- 一个名为
aibrix-runtime的容器,以aibrix_runtime --port 8080启动,镜像为aibrix/runtime:v0.5.0(可通过下方 image 注解覆盖); - 环境变量
INFERENCE_ENGINE:当工作负载设置了model.aibrix.ai/engine注解时取自该注解,否则根据引擎容器镜像名推断(vllm、sglang、tgi、triton、llamacpp,其余推断为unknown),同时注入INFERENCE_ENGINE_ENDPOINT=http://localhost:8000。注意:只有vllm能产出一个可以正常启动的 Runtime,所以请只把它注入到 vLLM 工作负载; - 容器端口
metrics(8080)、存活探针/healthz和就绪探针/ready; - 一个挂载在
/tmp/aibrix/adapters的adapter-storage卷,用于存放下载的适配器; - 资源请求
100mCPU /256Mi内存,上限500m/512Mi。
Webhook 注册在Deployment和StormService对象上,且failurePolicy: Ignore——Webhook 故障绝不会阻塞工作负载创建,最多只是 sidecar 没有被注入。
在 StormService 上启用
Sidecar 注入同样适用于 StormService 自定义资源,会注入到每个 role 的 Pod 模板中:
apiVersion: orchestration.aibrix.ai/v1alpha1 kind: StormService metadata: name: my-service annotations: model.aibrix.ai/sidecar-injection: "true" spec: template: spec: roles: - name: worker template: spec: containers: - name: vllm image: vllm/vllm-openai:latest # ...自定义 Runtime 镜像
通过注解可以指定自定义的 Runtime 镜像:
apiVersion: apps/v1 kind: Deployment metadata: name: vllm-server annotations: model.aibrix.ai/sidecar-injection: "true" model.aibrix.ai/sidecar-runtime-image: "aibrix/runtime:v0.5.0" # Custom image spec: # ...启用全局 Runtime Flag
要让控制器使用 sidecar 的 API,需要在启动 controller-manager 时打开全局开关:
# Enable runtime sidecar globally ./bin/controller-manager --enable-runtime-sidecar=trueRuntime 检测逻辑如下表所示:
| EnableRuntimeSidecar | 行为 |
|---|---|
false | 控制器始终使用引擎直连 API(8000 端口),即使 sidecar 已被注入 |
true | 控制器检测 Pod 中是否存在aibrix-runtime容器:存在则走 Runtime API(8080 端口),不存在则回退到引擎直连 API(8000 端口) |
这种设计保证了无论是否注入 sidecar,功能都能正常工作,提供了最大灵活性。
手动安装 Sidecar
如果偏好手动控制,可以直接把 Runtime sidecar 加入 Deployment YAML:
containers: - name: vllm image: vllm/vllm-openai:latest # Your main container configuration... - name: aibrix-runtime image: aibrix/runtime:v0.5.0 command: - aibrix_runtime - --port - "8080" env: - name: INFERENCE_ENGINE value: "vllm" # only vllm is supported - name: INFERENCE_ENGINE_ENDPOINT value: "http://localhost:8000" ports: - containerPort: 8080 protocol: TCP volumeMounts: - mountPath: /models name: model-hostpath volumes: - name: model-hostpath hostPath: path: /root/models type: DirectoryOrCreate独立安装(Kubernetes 之外)
如果你希望在 Kubernetes 之外的其他场景使用 Runtime,可以通过 pip 安装:
python3 -m pip install aibrix如需使用 nightly 版本,可以从源码安装:
cd $AIBRIX_HOME/python/aibrix && python3 -m pip install -e .指标标准化
不同的推理引擎暴露的指标各不相同,AI Engine Runtime 负责把它们标准化。与推理引擎相关的信息通过容器环境变量定义。例如,若 vLLM 在http://localhost:8000/metrics提供指标服务,可用如下命令启动 Runtime:
INFERENCE_ENGINE=vllm INFERENCE_ENGINE_ENDPOINT="http://localhost:8000" aibrix_runtime --port 8080Runtime 随后在http://localhost:8080/metrics提供结果:引擎暴露的每个指标都会原样透传,而对于有标准化规则的指标,Runtime 会额外输出一份以引擎无关的aibrix:前缀命名的副本。
下表列出了完整的标准化映射。SGLang 与 TRT-LLM 列描述的是代码中已存在的规则集(定义于 python/aibrix/aibrix/metrics/engine_rules.py);由于 Runtime 目前只能以INFERENCE_ENGINE=vllm启动,这两列暂时无法被选中启用:
| 标准名称 | vLLM 来源 | SGLang 来源 | TRT-LLM 来源 |
|---|---|---|---|
aibrix:queue_size | vllm:num_requests_waiting | sglang:num_queue_reqs | N/A |
aibrix:gpu_cache_usage_perc | vllm:gpu_cache_usage_perc | N/A | N/A |
aibrix:kv_cache_usage_perc | vllm:kv_cache_usage_perc | N/A | kv_cache_utilization |
aibrix:token_usage | N/A | sglang:token_usage | N/A |
aibrix:prompt_tokens_total | vllm:prompt_tokens_total | sglang:prompt_tokens_total | N/A |
aibrix:generation_tokens_total | vllm:generation_tokens_total | sglang:generation_tokens_total | N/A |
aibrix:generation_throughput | N/A | sglang:gen_throughput | N/A |
aibrix:time_to_first_token_seconds | vllm:time_to_first_token_seconds | sglang:time_to_first_token_seconds | time_to_first_token_seconds |
aibrix:time_per_output_token_seconds | vllm:time_per_output_token_seconds | sglang:time_per_output_token_seconds | time_per_output_token_seconds |
aibrix:e2e_request_latency_seconds | vllm:e2e_request_latency_seconds | sglang:e2e_request_latency_seconds | e2e_request_latency_seconds |
aibrix:request_success_total | vllm:request_success_total | N/A | request_success_total |
aibrix:cache_hit_rate | N/A | sglang:cache_hit_rate | N/A |
aibrix:kv_cache_hit_rate | N/A | N/A | kv_cache_hit_rate |
从 engine_rules.py 的实现细节看,vLLM 规则中除了核心的queue_size、gpu_cache_usage_perc、kv_cache_usage_perc、token 与延迟类指标外,还通过PassthroughStandardRule保留了vllm:num_requests_running、vllm:request_prompt_tokens、vllm:request_generation_tokens等调试指标;SGLang 也透传了sglang:num_running_reqs、sglang:num_used_tokens、sglang:func_latency_seconds。TRT-LLM 的映射则特意保持克制,仅覆盖 AIBrix 当前消费的指标。
透传模式与故障兜底
设置METRICS_RAW_PASSTHROUGH_MODE=1(或METRICS_ENABLE_TRANSFORMATION=0)可以跳过标准化副本,直接按引擎原始形态提供指标。如果某次抓取中某条规则执行失败,Runtime 会记录错误,并在该次抓取回退到原始透传,而不是丢弃指标。
vLLM 指标输出样例
以下是 Runtime 提供的 vLLM 指标输出样例(该样例采集于aibrix:命名引入之前,仅展示透传指标;当前版本还会额外输出上表所列的标准化副本):
# TYPE vllm:cache_config_info gauge vllm:cache_config_info{block_size="16",cache_dtype="auto",calculate_kv_scales="False",cpu_offload_gb="0",enable_prefix_caching="False",gpu_memory_utilization="0.9",is_attention_free="False",num_cpu_blocks="9362",num_gpu_blocks="81767",num_gpu_blocks_override="None",sliding_window="None",swap_space_bytes="4294967296"} 1.0 # HELP vllm:num_requests_running Number of requests currently running on GPU. # TYPE vllm:num_requests_running gauge vllm:num_requests_running{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 0.0 # HELP vllm:num_requests_swapped Number of requests swapped to CPU. # TYPE vllm:num_requests_swapped gauge vllm:num_requests_swapped{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 0.0 # HELP vllm:num_requests_waiting Number of requests waiting to be processed. # TYPE vllm:num_requests_waiting gauge vllm:num_requests_waiting{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 0.0 # HELP vllm:gpu_cache_usage_perc GPU KV-cache usage. 1 means 100 percent usage. # TYPE vllm:gpu_cache_usage_perc gauge vllm:gpu_cache_usage_perc{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 0.0 # HELP vllm:cpu_cache_usage_perc CPU KV-cache usage. 1 means 100 percent usage. # TYPE vllm:cpu_cache_usage_perc gauge vllm:cpu_cache_usage_perc{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 0.0 # HELP vllm:cpu_prefix_cache_hit_rate CPU prefix cache block hit rate. # TYPE vllm:cpu_prefix_cache_hit_rate gauge vllm:cpu_prefix_cache_hit_rate{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} -1.0 # HELP vllm:gpu_prefix_cache_hit_rate GPU prefix cache block hit rate. # TYPE vllm:gpu_prefix_cache_hit_rate gauge vllm:gpu_prefix_cache_hit_rate{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} -1.0 # HELP vllm:lora_requests_info Running stats on lora requests. # TYPE vllm:lora_requests_info gauge vllm:lora_requests_info{max_lora="0",running_lora_adapters="",waiting_lora_adapters=""} 1.7382173358407154e+09 # HELP vllm:num_preemptions_total Cumulative number of preemption from the engine. # TYPE vllm:num_preemptions_total counter vllm:num_preemptions_total{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 0.0 # HELP vllm:prompt_tokens_total Number of prefill tokens processed. # TYPE vllm:prompt_tokens_total counter vllm:prompt_tokens_total{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 148.0 # HELP vllm:generation_tokens_total Number of generation tokens processed. # TYPE vllm:generation_tokens_total counter vllm:generation_tokens_total{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 955.0 # HELP vllm:request_success_total Count of successfully processed requests. # TYPE vllm:request_success_total counter vllm:request_success_total{finished_reason="stop",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 4.0 # HELP vllm:iteration_tokens_total Histogram of number of tokens per engine_step. # TYPE vllm:iteration_tokens_total histogram vllm:iteration_tokens_total_sum{model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 1103.0 vllm:iteration_tokens_total_bucket{le="1.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 994.0 vllm:iteration_tokens_total_bucket{le="2.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 994.0 vllm:iteration_tokens_total_bucket{le="4.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 994.0 vllm:iteration_tokens_total_bucket{le="8.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 994.0 vllm:iteration_tokens_total_bucket{le="16.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 994.0 vllm:iteration_tokens_total_bucket{le="24.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 994.0 vllm:iteration_tokens_total_bucket{le="32.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 994.0 vllm:iteration_tokens_total_bucket{le="40.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 998.0 vllm:iteration_tokens_total_bucket{le="48.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 998.0 vllm:iteration_tokens_total_bucket{le="56.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 998.0 vllm:iteration_tokens_total_bucket{le="64.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 998.0 vllm:iteration_tokens_total_bucket{le="72.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 998.0 vllm:iteration_tokens_total_bucket{le="80.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 998.0 vllm:iteration_tokens_total_bucket{le="88.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 998.0 vllm:iteration_tokens_total_bucket{le="96.0",model_name="Qwen/Qwen2.5-Coder-1.5B-Instruct"} 998.0模型下载
AI Engine Runtime 支持从 HuggingFace、S3、TOS 等多个远程源下载模型。当控制平面需要与 Pod 交互以动态加载新模型时,这一能力非常关键。下载逻辑的底层实现在 python/aibrix/aibrix/runtime/downloaders.py,它按 URL scheme(s3://、gcs://、tos://、huggingface://、http(s)://)分发到对应的ArtifactDownloader实现;下载文件时统一先写.part临时文件再原子替换,目录下载则按 prefix 遍历并重建相对路径。
从 HuggingFace 下载
首先定义 HuggingFace 模型所需的环境变量:
# General settings export DOWNLOADER_ALLOW_FILE_SUFFIX="json, safetensors" export DOWNLOADER_NUM_THREADS=16 # HuggingFace settings export HF_ENDPOINT=https://hf-mirror.com # set it when env is in CN region然后使用 AI Engine Runtime 从 HuggingFace 下载模型:
python -m aibrix.downloader \ --model-uri deepseek-ai/deepseek-coder-6.7b-instruct \ --local-dir /tmp/aibrix/models_hf/从 S3 下载
首先定义 S3 模型所需的环境变量:
# General settings export DOWNLOADER_ALLOW_FILE_SUFFIX="json, safetensors" export DOWNLOADER_NUM_THREADS=16 # AWS settings export AWS_ACCESS_KEY_ID=<INPUT YOUR AWS ACCESS KEY ID> export AWS_SECRET_ACCESS_KEY=<INPUT YOUR AWS SECRET ACCESS KEY> export AWS_ENDPOINT_URL=<INPUT YOUR AWS ENDPOINT URL> # e.g. https://s3.us-west-2.amazonaws.com export AWS_REGION=<INPUT YOUR AWS REGION> # e.g. us-west-2然后使用 AI Runtime 从 AWS S3 下载模型:
python -m aibrix.downloader \ --model-uri s3://aibrix-model-artifacts/deepseek-coder-6.7b-instruct/ \ --local-dir /tmp/aibrix/models_s3/从 TOS 下载
首先定义 TOS 模型所需的环境变量:
# General settings export DOWNLOADER_ALLOW_FILE_SUFFIX="json, safetensors" export DOWNLOADER_NUM_THREADS=16 # AWS settings export TOS_ACCESS_KEY=<INPUT YOUR TOS ACCESS KEY> export TOS_SECRET_KEY=<INPUT YOUR TOS SECRET KEY> export TOS_ENDPOINT=<INPUT YOUR TOS ENDPOINT> # e.g. https://tos-s3-cn-beijing.volces.com export TOS_REGION=<INPUT YOUR TOS REGION> # e.g. cn-beijing然后使用 AI Runtime 从 TOS 下载模型:
python -m aibrix.downloader \ --model-uri tos://aibrix-model-artifacts/deepseek-coder-6.7b-instruct/ \ --local-dir /tmp/aibrix/models_tos/上述所有DOWNLOADER_*环境变量都在 python/aibrix/aibrix/envs.py 中被集中解析,包括下载目录、线程数、分片阈值(DOWNLOADER_PART_THRESHOLD,默认 64MB)、文件后缀过滤、S3/TOS 凭据与端点等,是理解下载器行为的第一手入口。
LoRA 适配器管理(Model Configuration API)
前置条件:此功能需要引擎以
--enable-lora启动,并设置环境变量export VLLM_ALLOW_RUNTIME_LORA_UPDATING=true。更多细节可参考 vLLM 官方文档 "Dynamically serving LoRA Adapters"。
假设你已部署好一个基础模型和 Runtime,现在想为它加载一个 LoRA 适配器。首先启动引擎与 Runtime:
# start the engine VLLM_ALLOW_RUNTIME_LORA_UPDATING=true vllm serve Qwen/Qwen2.5-Coder-1.5B-Instruct --enable-lora # start the runtime INFERENCE_ENGINE=vllm INFERENCE_ENGINE_ENDPOINT="http://localhost:8000" aibrix_runtime --port 8080加载 LoRA 适配器
curl -X POST http://localhost:8080/v1/lora_adapter/load \ -H "Content-Type: application/json" \ -d '{"lora_name": "lora-2", "lora_path": "bharati2324/Qwen2.5-1.5B-Instruct-Code-LoRA-r16v2"}'卸载 LoRA 适配器
curl -X POST http://localhost:8080/v1/lora_adapter/unload \ -H "Content-Type: application/json" \ -d '{"lora_name": "lora-1"}'查询引擎当前模型
curl -X GET http://localhost:8000/v1/models | jq { "object": "list", "data": [ { "id": "Qwen/Qwen2.5-Coder-1.5B-Instruct", "object": "model", "created": 1738218097, "owned_by": "vllm", "root": "Qwen/Qwen2.5-Coder-1.5B-Instruct", "parent": null, "max_model_len": 32768, "permission": [ { "id": "modelperm-c2e9860095b745b6b8be7133c5ab1fcf", "object": "model_permission", "created": 1738218097, "allow_create_engine": false, "allow_sampling": true, "allow_logprobs": true, "allow_search_indices": false, "allow_view": true, "allow_fine_tuning": false, "organization": "*", "group": null, "is_blocking": false } ] }, { "id": "lora-1", "object": "model", "created": 1738218097, "owned_by": "vllm", "root": "bharati2324/Qwen2.5-1.5B-Instruct-Code-LoRA-r16v2", "parent": "Qwen/Qwen2.5-Coder-1.5B-Instruct", "max_model_len": null, "permission": [ { "id": "modelperm-c21d06b59af0435292c70cd612e68b01", "object": "model_permission", "created": 1738218097, "allow_create_engine": false, "allow_sampling": true, "allow_logprobs": true, "allow_search_indices": false, "allow_view": true, "allow_fine_tuning": false, "organization": "*", "group": null, "is_blocking": false } ] }, { "id": "lora-2", "object": "model", "created": 1738218097, "owned_by": "vllm", "root": "bharati2324/Qwen2.5-1.5B-Instruct-Code-LoRA-r16v2", "parent": "Qwen/Qwen2.5-Coder-1.5B-Instruct", "max_model_len": null, "permission": [ { "id": "modelperm-bf2af850171242f7a9f4ccd9ecd313cd", "object": "model_permission", "created": 1738218097, "allow_create_engine": false, "allow_sampling": true, "allow_logprobs": true, "allow_search_indices": false, "allow_view": true, "allow_fine_tuning": false, "organization": "*", "group": null, "is_blocking": false } ] } ] }输出中可以看到三个模型条目:基础模型Qwen/Qwen2.5-Coder-1.5B-Instruct以及挂载在其下的lora-1、lora-2两个适配器(parent指向基础模型)。
制品委托(Artifact Delegation)机制
当请求体携带artifact_url而非本地lora_path时,Runtime 会先下载制品再加载——这正是 ModelAdapter 控制器实际发送的请求形态。这一逻辑实现在 python/aibrix/aibrix/runtime/artifact_service.py 的ArtifactDelegationService中:它按lora_name在本地目录(默认/tmp/aibrix/adapters)落盘、写入.aibrix_download_complete完成标记实现断点续传与并发去重,通过正则^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$校验名称并阻止路径穿越,随后把本地路径转发给引擎加载;卸载时还可按需清理本地制品。凭证则支持从请求直传或从 Kubernetes Secret 挂载目录(默认/var/run/secrets/aibrix)读取。
配置参考
命令行参数
aibrix_runtime接受如下命令行参数(实现在 python/aibrix/aibrix/app.py 的parse_runtime_args中):
| 参数 | 默认值 | 说明 |
|---|---|---|
--host | 0.0.0.0 | 监听地址 |
--port | 8080 | 监听端口 |
--enable-fastapi-docs | false | 开启 FastAPI 的 OpenAPI schema 与 Swagger UI |
环境变量
| 变量 | 默认值 | 含义 |
|---|---|---|
INFERENCE_ENGINE | vllm | 引擎类型。必须是vllm;设为其他值 Runtime 将启动失败。 |
INFERENCE_ENGINE_VERSION | 0.6.1 | 引擎版本。对 vLLM 而言,0.6.1 及以上版本才启用 LoRA 端点。 |
INFERENCE_ENGINE_ENDPOINT | http://localhost:8000 | 引擎的基础 URL。 |
METRIC_SCRAPE_PATH | /metrics | 在引擎上抓取的路径。 |
METRICS_ENABLE_TRANSFORMATION | 1 | 是否应用标准化规则。0强制原始透传。 |
METRICS_RAW_PASSTHROUGH_MODE | 0 | 按引擎原始形态提供服务指标。 |
PROMETHEUS_MULTIPROC_DIR | /tmp/aibrix/metrics/ | Prometheus 客户端的临时目录。 |
DOWNLOADER_LOCAL_DIR | /tmp/aibrix/models/ | 请求未指定目录时模型的下载位置。 |
DOWNLOADER_NUM_THREADS | 32 | 并行下载线程数。 |
DOWNLOADER_ALLOW_FILE_SUFFIX | (全部文件) | 要拉取的后缀列表(逗号分隔),例如json, safetensors。 |
DOWNLOADER_PART_THRESHOLD/DOWNLOADER_PART_CHUNKSIZE | 67108864 | 文件超过该字节数时按分片拉取,以及分片大小。 |
DOWNLOADER_FORCE_DOWNLOAD | 0 | 即使文件已存在于本地也重新下载。 |
DOWNLOADER_CHECK_FILE_EXIST | 1 | 跳过本地已存在的文件。 |
HF_TOKEN、HF_ENDPOINT、HF_REVISION | (未设置) | HuggingFace 凭据、镜像端点和 revision。 |
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_ENDPOINT_URL、AWS_REGION | (未设置) | S3 凭据与端点。DOWNLOADER_S3_MAX_IO_QUEUE(100)与DOWNLOADER_S3_IO_CHUNKSIZE(16777216)可调优传输。 |
TOS_ACCESS_KEY、TOS_SECRET_KEY、TOS_ENDPOINT、TOS_REGION | (未设置) | TOS 凭据与端点。DOWNLOADER_TOS_VERSION(v2)选择客户端 API,TOS_ENABLE_CRC启用校验和。 |
注解与 Flags
| 设置 | 含义 |
|---|---|
model.aibrix.ai/sidecar-injection: "true"(注解) | 请求 Webhook 向Deployment或StormService注入 Runtime。 |
model.aibrix.ai/sidecar-runtime-image(注解) | 要注入的 Runtime 镜像(覆盖默认值)。 |
--enable-runtime-sidecar(controller-manager flag,默认false) | 当 Pod 中存在aibrix-runtime容器时,让控制器使用 Runtime API。 |
HTTP API 参考
所有端点都通过 Runtime 端口(默认 8080)提供服务:
| 端点 | 说明 |
|---|---|
GET /healthz | 存活探针。进程启动后恒返回200。 |
GET /ready | 就绪探针。注入时用作 Pod 就绪探针。 |
GET /metrics | Prometheus 格式的标准化引擎指标。 |
POST /v1/lora_adapter/load | Body 为{"lora_name": ..., "lora_path": ...},在引擎上加载适配器。lora_path原样传给引擎,因此必须是引擎能打开的路径。另一种 body 形态{"lora_name": ..., "artifact_url": ...}会让 Runtime 先下载制品再加载;这是 ModelAdapter 控制器发送的形态。 |
POST /v1/lora_adapter/unload | Body 为{"lora_name": ...}。 |
GET /v1/models | 引擎当前服务的模型列表,从引擎代理转发。 |
POST /v1/model/download | Body 为{"model_uri": ..., "local_dir": ..., "model_name": ..., "download_extra_config": {...}}。仅model_uri为必填。 |
GET /v1/model/list | 列出本地目录中的模型。接受可选 JSON body{"local_dir": ...}(注意:尽管是 GET,但参数通过 body 而非 query 传递);不传则列出 Runtime 默认下载目录。 |
/v1/runtime/models/*与GET /v1/runtime/snapshot | 实验性引擎生命周期端点(activate、deactivate、sleep、wake、kv-limit),供 ModelClaim 使用。不建议直接调用。 |
深入:Runtime 模型生命周期与 ModelClaim 协作
最后一组实验性端点背后,是 python/aibrix/aibrix/runtime/model_runtime.py 中的ModelRuntime引擎生命周期管理器,以及 python/aibrix/aibrix/runtime/model_runtime_api.py 中对应的 FastAPI 路由(/v1/runtime/models/activate、/deactivate、/sleep、/wake、/kv-limit、/v1/runtime/models列表与/v1/runtime/snapshot)。
从源码结构看,这套机制包含几个值得关注的设计:
- 可插拔的执行器:
EngineLauncher(启动/停止/休眠/唤醒引擎进程)与KVController(通过kvctlCLI 设置 kvcached 共享内存段的容量上限)均为抽象基类;生产环境使用SubprocessEngineLauncher以独立 session 拉起 vLLM/SGLang 进程并为每个模型分配独立的KVCACHED_IPC_NAME,同时提供MockEngineLauncher供无 GPU 的本地测试使用。 - 崩溃安全的本地状态:engine_registry.py 的
EngineRegistry以"同目录临时文件 +os.replace"的方式原子持久化引擎元数据,使 sidecar 重启后能重新收养(re-adopt)存活下来的引擎进程。 - 抓取时只读的指标采集:model_runtime_metrics.py 挂载在同一个
/metrics上,输出每个 Pod 常驻模型数、各模型的 kvcached KV 用量、HBM 峰值、引擎状态与重启/收养/生命周期操作结果等aibrix:modelclaim_*指标,且collect()只读、不产生副作用。
小结
AI Engine Runtime 把"多引擎差异化"这一复杂性收拢到了 sidecar 内部:向上,它为控制平面提供指标、模型、适配器、生命周期四类稳定 API;向下,它封装了 vLLM 的指标标准化、多源模型下载与 LoRA 动态加载。安装上首选注解驱动的自动注入,配合--enable-runtime-sidecar开关即可让 LoRA 控制器按需走 sidecar 路径。需要进一步了解其内部设计,可阅读 AI Engine Runtime 设计文档;相关的 LoRA 控制器工作流与 ModelClaim 使用方式,分别见 LoRA 动态加载 与 ModelClaim。
【免费下载链接】aibrixCost-efficient and pluggable Infrastructure components for GenAI inference项目地址: https://gitcode.com/GitHub_Trending/ai/aibrix
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考