性能调优
最优性能参数配置
配置类型 |
配置项 |
最优配置 |
---|---|---|
调度配置 |
maxPrefillBatchSize |
|
maxPrefillTokens |
|
|
maxBatchSize |
表6中根据公式计算出的最大值。 |
|
maxPreemptCount |
10。 |
|
supportSelectBatch |
true |
|
模型配置 |
npuDeviceIds |
[0, 1, 2, ..., worldSize-1] |
worldSize |
节点的最大可用卡数。 |
|
npuMemSize |
表5中根据公式计算出的最大值,单位GB。 |
|
资源配置 |
preAllocBlocks |
表1范围内适当调小。理论上为ceil(数据集平均输出长度/cacheBlockSize)最佳,但当前不开满可能会卡死。 |
maxBatchSize调优指导
在mindservice.log日志中,过滤测试时间段对应的“COMPLETED REQ ID”关键字如下:
...COMPLETED REQ ID: 363 , 5 , 593 , 81 , 512 , 12 , 60 , 1 ...COMPLETED REQ ID: 377 , 5 , 237 , 87 , 150 , 12 , 60 , 1
- 前五列代表当前batch在本次decode推理完成的第一个请求的基本信息。
- 后三列代表本次decode推理的batch的基本信息。
性能的最优值就是根据第7列的NpuBlock使用个数和Total Block Num个数之间的关系调整BatchSize,具体调整策略如下:
- 如果在整个过程中,Block Num一直低于Total Block Num,那么说明BatchSize不足,适当调大。
- 如果在整个过程中,Block Num在部分请求段大于或等于Total Block Num,那么说明BatchSize过大,直接调小到该段对应的BatchSize附近。
操作步骤
这里以llama-65b模型为例进行最优性能的配置,环境信息举例如下:
- 本机显存大小为64G的卡,NPU数量为8卡,以已占用3G为例。
- 由于后处理在当前版本默认开启,以占用2G为例;如需关闭后处理,请参见如下方法,关闭后则不需要参与计算。
使用vim命令打开/usr/local/Ascend/mindie/latest/mindie-service/latest/bin/ibis目录中的model_inputs.py文件,注释第61-64行即可关闭后处理:
# elif input_tensor.name() == "SAMPLING": # has_sampling = True # if is_prefill: # sampling_param = np.array(input_tensor, copy=False)[0]
- 请参考表5中的“npuMemSize”参数计算出npuMemSize的值并根据计算结果调整配置中的该值,计算过程如下所示。
- 请参考表6中的“maxBatchSize”参数计算出maxBatchSize的值并根据计算结果调整配置中的该值,计算过程如下所示。根据计算公式:maxBatchSize = Total Block Num/Block Num,需要先计算出Total Block Num和Block Num的值。
- 计算Total Block Num的值。
根据计算公式:Total Block Num = Floor[NPU显存/(模型网络层数*Block Size*模型注意力头数*注意力头大小*Cache类型字节数*Cache数)],公式中各参数的取值信息如表2所示。
表2 Total Block Num公式中的参数值 参数
取值
NPU显存
1中npuMemSize的值。
模型网络层数
模型网络层数是模型权重文件config.json中的hidden_layers值,取值为:80。
Block Size
默认值:128。
模型注意力头数
“模型注意力头数*注意力头大小”的值为模型权重文件中config.json中的hidden_size值。
说明:对于llama2模型,由于是GQA类模型(分组查询注意力类模型),需使用模型权重文件config.json中num_key_value_heads的值作为注意力头数,而不是num_attention_heads。所以每张卡上的“模型注意力头数*注意力头大小”的值不一定是用hidden_size/卡数。例如llama2-70b的“模型注意力头数*注意力头大小”的值应该为8*128=1024,而不是hidden_size中的值:8192。
注意力头大小
Cache类型字节数
由模型config.json文件中的torch.dtype决定,一般为float16类型,取值为:2。
Cache数
默认值:2。
将以上参数值代入公式,得到Total Block Num=Floor[34*1024*1024*1024/(80 * 128 * 128 * 64/8 * 2 * 2)] = 870。
注:以上算式中64/8是由于有8张NPU卡,所以注意头数需均分在8张卡上。
- 计算Block Num的值。
根据计算公式:Block Num = Ceil(输入Token数/Block Size)+Ceil(最大输出Token数/Block Size),公式中各参数的取值信息如表3所示。
表3 Block Num公式中的参数值 参数
取值
输入Token数
首次一般参考数据集的平均输入,取值100。
第二次则可以直接取返回结果中的average_input_length的值。
最大输出Token数
从config.json文件中的maxIterTimes参数获取,取值:512。
Block Size
默认值:128。
将以上参数值代入公式,得到Block Num = Ceil(100/128)+Ceil(512/128) = 5。
“Ceil”表示计算结果向上取整。
- 根据2.a和2.b计算出的Total Block Num和Block Num值,然后使用公式maxBatchSize=Total Block Num/Block Num得到maxBatchSize的值。
maxBatchSize = 870/5 = 174。
- 计算Total Block Num的值。
- 根据2中maxBatchSize的值调整maxPrefillBatchSize和maxPrefillTokens的值,并将supportSelectBatch参数设置为“true”,详情请参考最优性能参数配置。
preAllocBlocks的值根据ceil(数据集平均输出长度/cacheBlockSize) 进行计算,约为1。
- 根据本机环境和选用的模型需要调整npuDeviceIds和worldSize的值,详情请参考最优性能参数配置。进行第一次调试,调试方法请参见llm_engine_test。
- 调整npuMemSize,在调试过程中,重开一个窗口使用以下命令查看占卡情况,如果剩余空间还很大,可以调大npuMemSize的值,重复2~4后再次进行调试。
watch npu-smi info
- 当npuMemSize的值不够大时,可以继续调大空闲值,如图1。
- 当npuMemSize的值过大时,则会报“Npu out of memory”错误,如图2所示。
- 根据“Npu out of memory”报错信息,将npuMemSize的值调小(比如在原来的值上减2,避免卡死),则可以达到最优npuMemSize的值。如图3,大概是占据95%卡的状态。
这时从性能返回结果可以看出来lpot会优于配置之前的值,并且generate speed也有很大的提升。
- 根据用户需求通过以下方式进行吞吐量最大化的配置或者非首token时延(lpot)最小化的配置。
- 吞吐量最大化
通过调整maxBatchSize的值使吞吐量最大化。首先根据结果日志(logs/mindservice.logs)使用以下命令查看最大Total Block Num的值,如图4所示。
grep "COMPLETED" mindservice*.log
从上图中查看Total Block Num的峰值为854,比计算得到的Total Block Num值小。即可适当调大maxBatchSize的值(同步调整对应的maxPrefillBatchSize、maxPrefillTokens和maxPreemptCount的值)再进行一次性能操作。
也可以通过将set_env.sh环境变量中打开Python日志(export MIES_PYTHON_LOG_TO_FILE=1),并在/workspace/log/pythonlog.log.xxxxx下对应日志中通过搜索npuBlockNum找到,如图5所示,值为896。
- 非首token时延(lpot)最小化
为了让非首token时延(lpot)最小化,则需要调小maxBatchSize来达到最优性能,暂时只能通过阶梯调整。
根据3对maxBatchSize进行调整,并调整对应的maxPrefillBatchSize、maxPrefillTokens和maxPreemptCount的值,对比哪个值可以达到要求。
maxPrefillTokens的值不能小于4096。
比如baichuan2-7b模型在Atlas 300I Duo 推理卡上进行的测试,lpot要求是小于80ms,这时maxBatchSize的值选择87时可以得到最小化的时延要求以及该时延下最优吞吐量。
表4 maxBatchSize对应的lpot和generate speed maxBatchSize
lpot(时延)
generate speed(吞吐量)
200
160
1145
100
88
1074
90
81
1058
89
80.4
1058
88
80.4
1060
87
79.7
1032
- 吞吐量最大化