Overview
Blitzscale充分利用了网络硬件(RDMA、NVLink)进行快速扩缩容,并通过zigzag prefill在扩容时通过类似PP的方式充分利用正在加载的replica算力,实现对在线服务突发负载下的scale up/scale out,以避免SLO violation的发生。
Build
hardware requirement
为了充分展示不同扩缩容方案的特点,需要有
- RDMA IB网卡
- NVLink
仓库目录下提供了Dockerfile容器环境,避免手动配置环境的复杂性
clone项目
git clone git@github.com:blitz-serving/blitz-remake.git
cd blitz-remake
构建容器
docker build -t blitz-docker .
# 运行容器时指定使用的IB网卡
# 指定容器使用全部GPU
# 建议将刚刚clone的blitz-remake仓库通过volume挂载到容器中
docker run -itd \
--privileged \
--gpus all \
--ipc host \
--network host \
--volume /data2:/nvme \
--device /dev/infiniband/rdma_cm \
--device /dev/infiniband/uverbs0 \
--workdir /root \
--name blitz-docker \
blitz-docker /bin/bash
安装rust
## 安装rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "/root/.cargo/env"
编译构建
对于不同架构的GPU,需要更改cmake编译选项,以4090、Hopper架构GPU各自的cmake命令为例
# 4090 使用CUDA_ARCHITECTURES=80,TORCH_CUDA_ARCH_LIST='8.0'
cmake -Bbuild/release \
-DTorch_DIR=/usr/local/lib/python3.10/dist-packages/torch \
-DBUILD_MODE=debug \
-DCMAKE_CUDA_ARCHITECTURES=80 \
-DFLASHINFER_CUDA_ARCHITECTURES=80 \
-DTORCH_CUDA_ARCH_LIST='8.0' \
-DFLASHINFER_ENABLE_FP8=false \
-DFLASHINFER_GEN_HEAD_DIMS=128 \
-DFLASHINFER_GEN_MASK_MODES=1 \
-DFLASHINFER_GEN_POS_ENCODING_MODES=1
# Hopper架构下修改对应的ARCHITECTURES
cmake -Bbuild/release \
-DTorch_DIR=/usr/local/lib/python3.10/dist-packages/torch \
-DBUILD_MODE=debug \
-DCMAKE_CUDA_ARCHITECTURES=90 \
-DFLASHINFER_CUDA_ARCHITECTURES=90 \
-DTORCH_CUDA_ARCH_LIST='9.0' \
-DFLASHINFER_ENABLE_FP8=false \
-DFLASHINFER_GEN_HEAD_DIMS=128 \
-DFLASHINFER_GEN_MASK_MODES=1 \
-DFLASHINFER_GEN_POS_ENCODING_MODES=1
# 若提示CMAKE_CUDA_COMPILER并未找到,则需要提供nvcc路径
# -DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc \
# 编译
cmake --build build/release -j 64
mpi
如果构建时报错无法找到mpirun,使用如下命令
export OPAL_PREFIX=/opt/hpcx/ompi
export PATH=/opt/hpcx/ompi/bin:$PATH
export LD_LIBRARY_PATH=/opt/hpcx/ompi/lib:\
/opt/hpcx/ucx/lib:/opt/hpcx/ucc/lib:\
/opt/hpcx/sharp/lib:/opt/hpcx/hcoll/lib:$LD_LIBRARY_PATH
测试
# 通过test_model_llama测试CUDA能够正常使用
./build/bin/test_model_llama
usage
启动server和router之后,由client向router发送推理请求,接口兼容openai
pip install toml
python ./scripts/batchv2/main.py --template ./config/e2e...
Telemetry(alpha)
在router中暴露/metrics端口,使用prometheus + grafana的方案作为telemetry,以实现可观测性
install
通过bin安装prometheus与grafana
https://prometheus.io/docs/prometheus/latest/getting_started/
https://grafana.com/docs/grafana/latest/setup-grafana/start-restart-grafana/
config
修改prometheus中的yml,从而更改拉取的时间间隔
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:11236"]
labels:
app: "prometheus"
run
./prometheus --config.file=prometheus.yml
./bin/grafana server
在grafana 3000端口grafana dashboard进行面板的修改、查看。后续附上重要metrics dashboard的yml配置
Architecture
Code Structure
-
request-sim: 模拟client发送请求
-
router_v2: Blitzscale主体部分,作为全局调度器、控制器,触发扩缩容,并通过调度逻辑将批处理请求发送到后端算子进行执行
-
- main: 主函数,解析传入参数并转换为Controller的参数
- server: 注册HTTP请求端点并运行server进行监听
- stub: 定义router向后端发送gRPC请求的方法
- queue: 请求进入系统后append添加到这个队列中,next_batch每次从队列中取出下一个batch
- lib: 定义使用到的各种结构体
- infer: Infer类,控制向request发送流式响应,并相应创建disaggregation/colocation的controller
- health/error: 使用到的健康/错误结构体
- replica: 与调度/扩缩容相关的代码
- disaggregation: PD分离下的控制类,进行调度、扩缩容
- colocation: PDColocation下的控制类
- metrics: 系统内负载的数据结构
- relay_queue 实现zigzag prefill的队列,转移的batch在这里存放
- mod: colocation相关的控制类
- config: 配置类
- cybernetics:
- exec_blitz: blitz中进行扩容的策略(tanz,rdmabroadcast,rdma p2p,nvlbroadcast...)
- exec_serverless: serverless llm的扩容方式,从磁盘/内存中加载参数
- mod: exec_blitz中执行参数发送的方法实现
- planner: 循环监控系统状态,并生成扩缩容计划
- steersman: 存储模型信息、replica与物理拓扑的映射等
-
-
src: 模型执行后端,在这里发送CUDA kernel给GPU进行模型执行,并且通过RDMA、Tanz、NVLink进行模型参数传递
- server: main函数所在的目录,初始化stub、service并启动grpc server
- service: grpc service实现的位置,实现向外暴露的grpc端点服务
- model: 抽象整个模型
- layer: 抽象模型单个层
- kernel: flashinfer相关算子,以及绑定算子实现的文件
- blitz: 关于activation传递、kvcache传递、pd migration、参数广播、参数加载等blitzscale核心逻辑
-
scripts: 运行整个系统测试的脚本
- batchv2: 当前可用脚本
-
config: 用于scripts测试的配置文件(toml)
Key implementations in each file are listed below...
Components
组件可基本分为三个
- router: rust实现,进行blitzscale核心zigzag、扩缩容的实现,接受client的推理请求,并将batch request发送给server进行推理。兼容openai接口
- server: c++实现,负责拉取参数,进行算子执行
- client: python实现的request-sim,用于测试时模拟客户请求
Router
在Huggingface项目Text Generation Inference的基础上,集成blitzscale扩缩容、zigzag与PD分离的逻辑
Disaggregation
请求处理
start_disaggregation_event_loop函数创建loop处理不同逻辑的Task
创建steersman记录每个replica的物理所在位置,spawn_migration_queue,并对每个replica spawn出disaggregation_event_loop_inner,以状态机的实现方式,向对应的replica发送请求,以及根据replica的状态进行请求的传递(zigzag/pd migration)。
之后,创建DisaggregationController,进行reject_kv_cache_event_loop(避免decode实例过载)和report_system_metrics
不指定manually_scale编译选项时spawn出auto_scale_event_loop进行自动扩容()
auto_scale_event_loop
在planner的replica_state_moniter_loop中 循环generate_scale_target,并判断当前扩缩容feature,对于blitz使用exec_blitz中的扩缩容方案,sllm使用exec_serverless中的方案。 exec_serverless直接向实例发送请求,从hostmem或者disk中加载参数 而exec_blitz则使用RDMA p2p, NVLink p2p, NVLink broadcast或Tanz等方式进行扩容
reject_kv_cache_event_loop
动态检测并锁定某些decode副本,防止继续接收kvcache请求。 遍历所有副本,并记录处于decode或Rdmasending状态副本的used_blocks。之后如果发现有decode使用的blocks高于平均值的两倍,则锁定该副本。 实际执行上会与上次锁定的副本进行比较,只锁定新增的副本。
report_network_flow
收集每个replica的flow_in和flow_out,构建flow_map用来打印日志
report_system_metrics
遍历每个replica_metric,打印state,used_blocks以及是否加载模型等信息
report_cur_waiting_prefill_tokens
当前deprecated
disaggregation_event_loop_inner
核心循环,以状态机的方式实现对不同replica状态的逻辑,包括batch发送,请求migration等逻辑。对于每个replica,都创建出处理当前replica的event_loop。传入参数如下
- 用于同步的init_guard
- 状态切换命令的ReplicaCommand Channel
- queue
- migration queue
- replica_metric
在循环中每次取出当前replica状态,尝试接收Command并根据状态执行不同的处理逻辑。没有接收到Command就直接使用当前状态
inactive/loadingprefill/loadingdecode
yield等待
shuttingnull
将当前replica上锁,避免被其他进程操作。 yield等待
decode
循环从migration_queue中try_consume batch(tokens batch entries)并压入global_batch。如果global_batch已经为空则yield释放,否则进行一次Decode 包括对系统metric进行设置,将batch和last_token通过stub发送给后端(decode_v2),将generations通过stream sender发送给等待向流式请求返回响应的线程。如果是最后一个token返回InferStreamResponse::End,否则返回InferStreamResponse::Intermediate,接收者会进行不同的处理。当前loop会在请求生成最后一个token时从entries中移除该请求。之后将结束的请求向server发送clear_cache,未结束的请求发送filter_batch并重新放入global_batch,进行下一轮处理
prefill
如果当前需求的block已经大于每个replica最大的block数,则yield 否则从queue中调用next_batch得到下一个prefill batch,增加使用的blocks计数,构造PrefillCase::Normal的prefillRequest,调用stub.prefill_v2得到prefill的Response,发送InferStreamResponse::PrefillDone & InferStreamReponse::Intermediate | InferStreamResponse::End,并判断client是否quit,如果由于client quit或Response::End则从entries中移除,并根据移除情况进行clear_cache / filter_batch 由于是PD分离,将Prefill的结果构造为MigrationBatch,通过flow_watcher和migration_queue进行传递(batch entries tokens),交由Decode实例进行Decode阶段
newprefill
用于ZigZag执行的前半段,确保当前replica持有锁 初始化zig_zag相关的时间戳并检查模型是否已经加载 模型已加载则从pending_zag_prefill队列头部取出batch和前半段prefill的response,执行post_prefill_pre_decode。然后create_refact_head_task创建任务(循环从pending_zag_prefill请求中取出等待,并将将结果进行filter和send),切换到RefactoryPrefill状态,进入下一轮循环 如果当前replica使用的block已经超上限,则yield进入下一轮循环 如果模型未加载完毕,则从Relay_queue中尝试取出relay请求,向所有stub发送relay请求等待response(将完成的前半段请求传递给old prefill)。 如果response中包含batch_id和seq_num,则循环从pending_zag_prefill中pop。如果pop出的prefill response start_layer为空则post_prefill_pre_decode,并修改model_loaded为true,否则break循环。此时已经得到start_layer非空的request,根据start_layer类型,transformerlayer部分迁移,向migration_queue append_partial_fst,之后通过sender通知OldPrefill(forwardcase为naivepp和immigrate)。embeddinglayer则直接迁移,同样sender通知OldPrefill(forwardcase为normal)并通知所有stub clear_cache 如果response中不包含batch_id和seq_num,则重新判断model_loaded。如果model_loaded被置为true
之后判断pending_zag_prefill的长度并yield控制zigzag速率 从batching_queue中获取下一个batch并发起新的zigzagprefill,压入pending_zag_prefill队列等待后续处理
refactoryprefill
这个状态用于批量处理pending_zag_prefill队列中的任务,在relay_queue中检查relay请求,如果有则进入relay处理流程 relay处理流程首先向所有stub调用relay操作(传入relay_rank),如果response中包含了batch_id和seq_num,则说明有batch需要迁移,取出pending_zag_prefill中对应的future,等待完成之后判断response的start_layer,根据transformer和embedding进行NewPrefill中同样的处理。 如果response不包含batch_id,说明迁移已经完成,统计pending_zag_prefill并进行异常检查,通过sender通知OldPrefill,等待refactory_head_task结束之后重置状态为Prefill
oldprefill
用于ZigZag执行的后半段 调用全局relay_queue的append,在这里通过async_channel_sender发送请求(indices: 当前所在PP rank),等待收到PartialPrefill请求。 收到partialprefill请求后调用prefill_v2并执行filter、send逻辑。 如果请求的start_layer是TransformerLayer,则PartialMigration(append_partial_snd,因为前半段prefill也有kvcache需要migration),指定层级迁移部分kvcache;如果是EmbeddingLayer则append迁移整个batch的kvcache,因为此时当前replica保有全部的kvcache 这两者的不同会在spawn_migration_queue中进行分别处理。 如果在relay_queue中没有拿到partialprefill请求,则等待relay_cnt归零将状态切换为Prefill
mutatingtodecode
向Migration_queue发送Flush命令,将所有属于当前replica未迁移的batch一次性取出,放入global_entries和global_batches,供decode后续使用。 之后状态切换为Decode
auspreflil
持锁之后转变为prefill
ausdecode
持锁之后转变为decode
shuttingdecode
decode状态切换到彻底关闭的清理状态,目的是完成所有剩余的decode任务。如果global_batches为空并且持有锁则切换到shuttingNull 如果还没有持有锁,则尝试异步获取锁防止并发冲突(或yield等待join_handle结束持锁) 获取到锁之后不断从migration_queue中消费属于本副本的migration_queue,并循环从global_batches中取出request进行decode,同样对每轮生成filter_send_generations,直到global_batches被清空
shuttingprefill
当unfinished_migration_count归零时切换到ShuttingNull,否则yield等待 unfinished_migration_count会在向migration_queue中压入batch时increment
sending/loading/casting
panic
扩缩容
通过状态机进行状态的切换
exec_blitz
对于传入的扩缩容计划,进行针对性的扩缩容,判断依据是prefill和decode各自的计划
- 优先将Shutting副本转换为正常副本
- 复用Null副本 避免冷启动
- 带宽、拓扑感知的数据迁移
- 首先考虑节点内的扩容,nvlink broadcast
- 之后考虑节点间的扩容,使用rdma p2p/tanz或者rdma broadcast
- 最后考虑直接新建、关闭副本
根据(prefill_plan, decode_plan)的不同执行不同的扩缩容计划
-
(scaleup, scaleup): 先将shutting_decode/shutting_prefill副本转换为正常副本。如果还有需求就将shuted副本转换为prefill。如果支持nvlink,则通过steersman指定nvlink chain,通过chain进行nvlink scale。如果仍然无法满足需求,则进行rdma_sending。根据编译时feat选项的不同,使用live_p2p或tanz或rdma broadcast/p2p进行扩容
-
(scaleup, stay): 首先将shutting_prefill转换为prefill,之后shutted转换为prefill。然后指定nvlink chain进行chain broadcast。最后进行节点间的扩容,通过p2p或者tanz/rdma broadcast完成
-
(stay, scaleup): 将shutting_decode转换为decode,然后shutted转换为decode,之后进行nvlink broadcast节点内扩容。再进行节点间扩容
-
(scaleup, scaledown): 需要将shutting prefill转换为prefill,shutted转换为prefill。将未使用的shuttingNull转换为inactive,通过向server发送reset_status grpc来实现。如果还需要扩容prefill,则考虑发送参数。
-
(scaledown, scaleup): 将shutting decode转换为decode,shuttingnull转换为decode。然后进行节点内nvlink broadcast。与上面情况不同的是,此时可以将prefill转换为decode replica,直接复用prefill实例的参数,将prefil实例转换为mutatingToDecode实例。之后进行节点间扩容,使用rdma broadcast/p2p或者tanz进行参数传播。
-
(stay, stay): 简单的判断shuttingNull关闭时间,并转换为Inactive
-
(stay, scaledown): 将shuttingNull deactivate,如果仍然需要缩容,则将decode转变为shuttingdecode
-
(scaledown, stay): 将shuttingNull deactivate,如果仍然需要缩容,则将prefill关闭为shuttingPrefill
-
(scaledown, scaledown): 将shuttingNull deactivate,并关闭prefill和decode的实例
Infer
infer类是进行推理和手动扩缩容的实现类 generate_stream接收流式推理请求,将请求压入Queue之后即退出,等待流式的返回token。对请求的调度等实现在disaggregate中。由server中的处理函数对stream进行await和SSE推送响应,response的类型如下。
- PrefillDone
- Prefill
- Intermediate
- End
migration_queue
spawn出migration_queue_task 接收MigrationCommand
- Produce: 插入waiting_full_batches
- ProducePartial: 插入waiting_partial_batches
- Flush: 清空全部的waiting_full_batches,并向请求者发送迁移走的全部batch
- 如果没有正在进行的partial_migration,并且等待队列中还有partial_batches 循环选择可用的目标replica,通过对dst_mutex尝试上锁,并且判断状态不为ShuttingNull。为了避免overflow,还需要保证dst_replica存在足够的block。这样就选中了可用的目标replica。添加使用的block并调用doing_partial_migration,spawn出新的task传递partial_kvcache,传递结束时free src的blocks。将这个task通过fst2snd_tx发送。 如果没有fst2snd_tx,则直接spawn出线程执行partial_kv_cache的传递
- 如果没有正在进行的full_migraion,并且存在等待的full_batches: 同样选择可用的目标replca,spawn出线程执行trans_kv_cache
对于trans_kv_cache,通过向目标stub发送migrate和immigrate,传入要传递的batch和src_ranks,dst_ranks。trans_partial_kv_cache则只需要判断fst_layer或者snd_layer向stub发送immigrate_fst或immigrate_snd(migrate_fst, migrate_snd)
planner(TODO)
由create_disaggregate_inner创建的循环 在这里记录rdma和nvl的状态
循环查看replica_state,并生成扩容计划。根据编译选项,通过execute_scale_plan_blitz或者execute_scale_plan_serverless不同方式执行扩容计划
view_replica_state遍历所有replica_state,收集每个replica的metric。 LoadingDecode AusDeocde和MutatingToDecode统一记录为decode replica,而Prefill AusPrefill NewPrefill OldPrefill RefactoryPrefill和LoadingPrefill都记录为prefill replica
generate_scale_target(TODO)
Colocation(TODO)
Client
Server
通过MPI多机/单机内启动之后,首先初始化MPI和CUDA设备,之后初始化用于处理grpc请求的Stub,初始化Tokenizer和gRPC serviceImpl,将service注册处理的stub并开始监听服务。监听之前注册sig_handler,接收到SIGINT等信号之后调用回调函数,通知poller线程终止server监听 在Stub初始化时初始化相应的模型、CacheManager和MigrationManager、ModelLoader和Activation_manager、zigzag_manager并初始化NCCLBroadcastor
Tccl
在Server中,网络传递params/kv_cache通过Tccl和nccl完成
Model
初始化flashinfer的handler,并分配weight_segment,runtime_segment,以及ragged_indptr_d等小的内存区域 对所有的子层(embed,transformer,和lm都进行初始化)
CacheManager
分配kvcache的GPU区域和cpu区域
MigrationManager
在这里通过cudaEventCreateWithFlags创建CUDA事件,用于在GPU上进行异步操作的计时和同步
ModelLoader
分配host内存
ActivationManager
分配num_activation_slot * activation_slot_size_in_bytes大小的区域存放activation 创建新的线程,循环等到被唤醒,用于NaivePP或者Zigzag pp的activation传递
ZigzagManager
创建线程循环等待唤醒,并调度task进行执行。 执行时首先判断执行到的层数,如果未执行,则执行prologue,由embed层进行前向推理 之后forward后续的层,如果执行了最后一层则执行epilogue从task_queue中移除。 主循环event_loop_inner不断从队列中取出任务,推进transformer layer。sched_next_task获取下一个要处理的任务。如果是新任务,首先执行prologue中的embedding,否则判断当前执行到的层级,进入transformer层的推进。如果interrupt_residual传入了外部中断的请求则调用epilogue将任务relay给peer。否则在本地fwd_one_layer推进,任务完成时调用epilogue采样 手机结果。支持抢占,如果有新任务到来可以中断当前任务。
NcclBcastor
创建线程绑定nccl_bcastor_worker_inner任务 设置线程使用的GPU设备,确保后续CUDA/NCCL操作在正确的GPU上执行,然后初始化点对点的P2P通信 当唤醒时,通过普通的链式广播/环式广播并行广播,提升带宽利用率。并统计广播的耗时和带宽
export CUDA_VISIBLE_DEVICES="0,1"
Scripts
batchv2是当前的使用脚本,batch目录中的脚本已经deprecated 示例命令如下(要根据需求修改toml配置,详见usage)
python ./scripts/batchv2/main.py --templates ./config/e2e-blitz.toml
Args
- templates
- default: none
- 指定template file的路径
- checkpoint
- default: none
- 指定到archive home的路径
- force
- default: False
- 是否忽略checkpoint
- dry-run
- default: false
- 不执行任何实例的运行脚本
- color
- default: False
- 是否启用颜色化的输出
其中templates和checkpoint至少需要指定一个,否则无法运行
template中的配置可以参考/config目录下的toml配置文件
如下以e2e-blitz.toml为例
[global]
num_gpus_per_node = 4
cuda_devices = [0, 1, 2, 3, 4, 5, 6, 7]
[selection]
models = ["llama3_8b"]
features = ["blitz_ultra"]
datasets = ["AzureConv2023-5min"]
[server]
ibv_rate = 100
inter_node = true
[server.config]
g0001 = "10.254.0.10"
g0002 = "10.254.0.9"
[router]
port = 11236
max_prefill_num = 13
max_decode_num = 13
min_prefill_num = 1
min_decode_num = 1
prefill_lower_bound = 0.5
prefill_upper_bound = 0.8
decode_lower_bound = 0.75
decode_upper_bound = 0.95
migration_lower_bound = 0.2
migration_upper_bound = 0.4
scale_down_threshold_millis = 333
mock_load_millis = 0
mock_transfer_millis = 0
# Extra envs when launching server, router and client.
# CUDA_VISIBLE_DEVICES is set in [global] section and will be ignored if set here.
[extra-envs]
LOG_LEVEL = "INFO"
[features]
sllm_cache_replace = "ngrok,impl_sllm,cache_replace"
sllm_optimal = "ngrok,impl_sllm,cache_all_hit,mutate"
blitz_ultra = "ngrok,impl_blitz,impl_live_pro,impl_fast_pro,mutate"
blitz_tanz_debug = "ngrok,impl_blitz,impl_fast_pro"
blitz_live_tanz_debug = "ngrok,impl_blitz,impl_live_pro,impl_fast_pro"
[datasets]
[datasets.AzureCode2023-90sec]
dataset_path = "./dataset_home/AzureCode2023-90sec.csv"
time_in_secs = 20
[datasets.AzureCode2023-130sec]
dataset_path = "./dataset_home/AzureCode2023-130sec.csv"
time_in_secs = 20
[datasets.AzureConv2023-5min]
dataset_path = "./dataset_home/AzureConv2023-5min.csv"
time_in_secs = 150
[models]
[models.llama2_7b]
model_path = "/nvme/blitz/models/Llama-2-7b-hf"
tokenizer = "/nvme/blitz/models/Llama-2-7b-hf/tokenizer.json"
tokens_prefilled_per_sec = 13000
tokens_transferred_per_sec = 30000
num_hidden_layers = 32
num_available_blocks = 8000
tp_size = 1
[models.llama3_8b]
model_path = "/nvme/huggingface/models/DeepSeek-R1-Distill-Llama-8B"
tokenizer = "/nvme/huggingface/models/DeepSeek-R1-Distill-Llama-8B/tokenizer.json"
tokens_prefilled_per_sec = 12000
tokens_transferred_per_sec = 60000
num_hidden_layers = 32
num_available_blocks = 30000
tp_size = 1
[models.mistral_24b]
model_path = "/nvme/huggingface/models/Mistral-Small-24B-Instruct-2501"
tokenizer = "/nvme/huggingface/models/Mistral-Small-24B-Instruct-2501/tokenizer.json"
tokens_prefilled_per_sec = 6000
tokens_transferred_per_sec = 40000
num_hidden_layers = 40
num_available_blocks = 8000
tp_size = 2
[models.qwen_72b]
model_path = "/nvme/huggingface/models/models--Qwen--Qwen2.5-72B-Instruct/snapshots/495f39366efef23836d0cfae4fbe635880d2be31"
tokenizer = "/nvme/huggingface/models/models--Qwen--Qwen2.5-72B-Instruct/snapshots/495f39366efef23836d0cfae4fbe635880d2be31/tokenizer.json"
tokens_prefilled_per_sec = 7500
tokens_transferred_per_sec = 40000
num_hidden_layers = 80
num_available_blocks = 8000
tp_size = 8
Control Flow
指定template时,将template文件中的配置通过instantiate_template函数进行解析,读取模板中的配置项
selection中指定models、features、datasets(lists),其中对每个model的详细配置在[models]中指定,包括model_path、tokenizer、tokens_prefilled_per_sec、tokens_transferred_per_sec等
对所有model的详细配置与datasets的详细配置、features的详细配置进行组合,与router的配置一同传入instantiate_template_router,得到用于实例化的router配置
run_instances中 首先启动server和server_monitor(监控),启动完毕启动router和client,并等待client正常退出
Args
Usage
当前脚本在python运行时,会首先通过mpi在inter-node/intra-node中启动多个server进程,之后运行router和client。client向router发送replay/mock/...的模拟请求,router在接收到请求之后会进行请求处理、自动扩缩容,并通过grpc向server发送request请求处理
如果希望batchv2脚本修改client发送请求的逻辑,例如从dataset的replay切换到mock随机生成数据模式,需要修改runner.py里_dump_client_bash_script和launch_client中启动client的脚本命令,注释掉--replay-mode项,并将--dataset-type项修改为mock,以使用mock模式的client发送请求,无需提前准备数据集
运行脚本前需要使用python安装所需依赖。启动server、client、router的命令会在log_home目录下
Example1
Question
- 自动扩缩容generate_scale_plan