PaddleOCR应用硬伤和MiniCPM-V(已改名为MiniCPM-o)Finetune踩坑后的纪录与分析。
MiniCPM-V 2.6 finetune準确率、Transformer架构与vLLM速度验证。
reference:https://github.com/PaddlePaddle/PaddleOCR、https://github.com/OpenBMB/MiniCPM-o、https://modelbest.feishu.cn/wiki/LZxLwp4Lzi29vXklYLFchwN5nCf
一. 此篇网誌撰写之背景
2024年是我目前职涯中变动最大的一年,几年前从原本单纯的AP 开发Team被主管拉去做Hadoop大数据,2024下半年开始争取进入AI Team,也有一个超强的AI技术职主管带领,但半年后主管离职,我在AI Team只剩3人(我+2个会AI的新人小朋友)的情况下,正式进入AI模型训练与应用的世界,但也是因为技术主管离职,靠着自己钻研今天我才写得出来这篇网誌(笑)。
二. 前言
本篇与各位在网路上所搜寻到的MiniCPM-V介绍文章不同,网路上的文章大多是介绍使用MiniCPM-V pretrained model如何使用以及使用心得,本篇是将pretrained model经过finetune后在凭证OCR的场景完成end to end落地应用,并取得不错的辨识效果。
我会先从一开始使用PaddleOCR实作后遇到的问题切入,并说明PaddleOCR无法克服的硬伤(我不是要批评PaddleOCR,的确在某些场景应用上,PaddleOCR和MiniCPM-V的準确度差不多,但PaddleOCR的推论速度大胜),最后带到为什么需要使用大语言模型MiniCPM-V去解OCR,同时将MiniCPM-V官方没有说明清楚的finetune流程,以个人实作过后的经验做分享。
文章很长东西很多,若只想看MiniCPM-V 2.6 finetune重点的可以直接跳到第五部分,但若跟我一样属于OCR初学者,建议从头看完会比较有感。
三. PaddleOCR的接触与应用
PaddleOCR其实已经问世很久也很多人使用,推论的速度也是非常的优秀,刚进AI Team的时候,技术主管带着我们做OCR的专案也是用PaddleOCR,但随着公司的应用场景越来越複杂,需要进一步tune模型时,其问题也慢慢浮现:
(一). 以一个OCR小白初接触的观点来看,finetune的相关文件似乎没有揭露得很清楚
举例来说我们finetune到后来发现很重要的data augment参数如CopyPaste(我们后来tune出来的模型,证实这是非常重要的参数),在官方的yml档上也只是显示空白,没有告诉你要写什么,我跟团队里的小朋友花很多时间在找finetune里的yml设定到底要怎么写,甚至还去读PaddleOCR image augment的code,到处去翻网路上其他前辈的training yml档,才兜出设定档来。
(二). 推论后的结果,回传顺序在某些状况下会遇到问题
以下面这张高铁票来说,我们想要辨识乘车日期、起讫站名、票价与票号,在PaddleOCR的detection与recgnition模型训练上是没有任何问题的,东西都可以正确抓到并且辨识出来,但实务上如果要回传结果给使用者,我们必须清楚地告诉人家起站与迄站分别是哪两个名称,在票面上没有任何key-value的对应情况下我们是不会知道的,仅能用站名是几个中文字这样的规则,以及回传顺序(PaddleOCR回传顺序是由左至右,由上而下)去将起迄站资讯取出来。
但我们可以发现下面这张高铁票经过PaddleOCR辨识后,起讫站的顺序明显给颠倒了,这是因为PaddleOCR除了使用上述规则判断外,也有对于列在同一行的资讯做一些处理,同一行侦测框高度差在某个门槛值内会被视作同一行,靠左边的物件顺序会在比较前面,程式码在这里https://github.com/PaddlePaddle/PaddleOCR/blob/main/tools/infer/predict_system.py。
但这样的做法就会造成当图片有些许歪斜或是内容排列不工整时,侦测框顺序就会错乱,即使你去调门槛值也无济于事,我也有参考网路上其他大神的修改方式调整排序,遗憾的是这种做法最终没有办法解决因歪斜与排列不工整造成的顺序错乱问题。
(三). 侦测框大小参数det_db_unclip_ratio无法一体适用的调整问题
这项也是我们在训练PaddleOCR要辨识多种凭证时发现的无解问题,例如下面的电子发票推论后可以发现,似乎在det_db_unclip_ratio设定为1.5的情况下会有发票号码无法完全包覆的问题,这会造成后续rec模型在辨识侦测框里面的字时辨识错误(因为东西没有框完整),但同样的设定在辨识高铁票上却没有框框过小的问题。
此时若我们调大det_db_unclip_ratio为3.0,让电子发票号码可以完全框住(其实也没完整框到),却发现其他侦测框过大概到其他区域,没有办法用一个设定值cover所有的侦测框,同时det_db_unclip_ratio=3.0的设定,对高铁票来说,侦测框又变得太大。
上述情形,尤其遇到文本中的资讯过于密集时情况会更恶化,资讯过于密集代表侦测框需要分常準确的框住你要侦测的物件上,稍有不準就会框到杂讯,造成后面的rec模型辨识度差。
(四). 模型推论完成后的资讯撷取Parsing不易
虽然PaddleOCR有KIE(Key Information Extraction)的功能,但实务上我们要辨识的东西很多是没有key-value可以让你这样标的(例如台铁、高铁车票),这也导致后续将资讯取出只能靠顺序、关键字等方法去撷取,这会造成资讯撷取正确率非常不稳定,即使有key-value,也会遇到很奇琶的问题,举例如下图,我们辨识某票证上面有买方公司行号名称,但实务上我们就发现有那种"买方"变成"买受人"字样的问题。站在user的立场,我们也不能说这样的东西是有问题的,只是case比较少,但还是要求我们要解决,但我们不可能无限制的去加关键字解这种问题,这会增加维运的effort。
整体来说,个人认为PaddleOCR适合应用的情形如下:
- 格式工整的文件如PDF电子档
- 内容不会太密集的文件(像电子发票就不太适合)
- 格式与内容不太会大变动的文件(像台铁与高铁票就不太适合,偶而会面临大改版)
如果是要辨识手拍照片、政府公文、纸本车票,实际应用上会出现很多问题,尤其是像电子发票这种,每一个商家开出来的发票字型都长得不太一样,宽度和密集度也都长得不一样,至少我们直接用PaddleOCR试过之后,真的是不太适合,可能在推论前必须要教育user拍摄图片的方式以及对图片做透视变换之类的前处理,才能有效提升正确率。
四. PaddleOCR上线后的痛苦挣扎期
前一段我们提到PaddleOCR推论完后资讯取得的问题,其实这才是整个OCR最重要的环节,如果不能精準的告诉使用你模型的人他想要辨识的字是什么,那模型等于没有用。第一阶段PaddleOCR模型上线后,我们家小朋友一直接到前端反馈有什么图片里面的字侦测不到,从log里面看到的状况是,一旦出现key关键字变动、图片歪斜稍微多一点或是出现资料集里较少甚至没有的图,就容易辨识有误(例如电子发票的票号字型和宽度千变万化,是我们模型最常被反应有问题的栏位,但也是user最care的栏位)。
有鉴于此,我一直在思考有没有办法训练一个模型,OCR完成后可以依照我想要的格式吐结果,省去后续parsing维运的effort和风险,要快速有效的话其实直接接线上有的大语言模型API是个不错的解法,现在的chatgpt其实OCR能力已经相当优秀,但毕竟它不是针对特定场景做finetune,吐回来的结果会有模型自己的加工,东西也不见得是正确的,最令人头痛的是吐回来的结果中的key-value不会每次都一样,这也会造成后续parsing的困扰。经过我们自己想要应用的场景实测,其栏位辨识正确率也才80%左右,与其他同事之前使用在其他场景统计出来的正确率差不多。
此时我们发现MiniCPM-V的存在,当时它已经从MiniCPM-V 1.0、MiniCPM-V 2.0、MiniCPM-Llama3-V 2.5一路出到MiniCPM-V 2.6,尤其2.6是个8B参数的模型,我其实不是很确定公司的机器是否效能足以使用(公司使用NVIDIA RTX 6000 Ada Generation,单卡GPU记忆体也才48G),但抱着试试看的心态,我踏上MiniCPM-V POC的旅程。
五. 开源大语言模型MiniCPM-V POC
MiniCPM-V我try过2.0、2.5、2.6这三个版本,使用的都是full-finetune(lora-finetune有try过后效果不佳就不考虑了),其中2.0的版本你照官方给的格式去做资料训练,会遇到data fetch error的问题https://github.com/OpenBMB/MiniCPM-o/issues/652,但依照别人的issue回馈改一下程式码一样可以练得出来,整体来说依据公司需要的场景finetune后我自己的结论如下表:
模型版本 | 模型释出时间 | 参数量 | 全量微调后效果 |
---|---|---|---|
MiniCPM-V 2.0 | 2024.02.01 | 2.8B | 推论速度约2秒,準确度差强人意 |
MiniCPM-Llama3-V 2.5 | 2024.05.20 | 8B | 推论速度约4秒,準确度较2.0强,已达可实际应用等级 |
MiniCPM-V 2.6 | 2024.08.14 | 8B | 推论速度约3秒,準确度较2.5更好,已达可实际应用等级 |
MiniCPM-o 2.6 | 2025.01.13 | 8.67B | 2025/1/13才出来,我还没时间try >.< |
基于以上初步POC速度上的结论,我选了MiniCPM-V 2.6往下继续做模型的优化和使用。
(一). 模型全量finetune需参考的文件
踩了这么多坑,最后发现其实只要看两个地方的文件就好,分别是github上的V2.6最佳实践以及飞书上作者写的比较细的finetune指南。
https://github.com/OpenBMB/MiniCPM-o/blob/main/finetune/readme.md
https://modelbest.feishu.cn/wiki/HvfLwYzlIihqzXkmeCdczs6onmdhttps://modelbest.feishu.cn/wiki/LZxLwp4Lzi29vXklYLFchwN5nCf
其模型的前处理原理以及token数计算,可以参考MiniCPM-Llama3-V 2.5的部分,有详细的解说。
https://modelbest.feishu.cn/wiki/X15nwGzqpioxlikbi2RcXDpJnjd
(二). WSL2环境準备
我是自己争取进入AI Team的,公司没有配有Nvidia GPU的电竞笔电给我,我是用之前为了研究Yolo模型在1111档期的时候去京东商城买了一台有RTX4060的显卡笔电自己弄(当然这张卡是不可能训练和使用大语言模型的,但把环境装起来这件事情基本上还是可以的)。我是在Windows作业系统上使用WSL2安装ubuntu 22.04后,生出docker image出来再转移到公司的GPU Server上使用,架构基本上跟我前一篇文本纠错网誌使用的架构是一样的。
https://dotblogs.com.tw/Ryuichi/2024/06/29/171320
使用WSL2的好处就是快速且方便,且不用另外準备一台电脑安装作业系统。但我使用了半年以上,发现其实还是有一些问题(不过都是可以克服的),通常都是发生在Windows做了例行性更新后:
- GPU可能会在工作管理员中消失,此时你在WSL2中下指令docker run -itd --gpus all时会整个hang住无法建立container,解决方法只需要去BIOS异动中选择进阶→显示模式→选择仅有dGPU,之后启动Windows时就会发现GPU出现并可使用了(这个我当初也是卡好久,最后才发现是这个很瞎的问题)。
- WSL2里面的cuda相关.so的档案,在执行时通常需要的是软链结,但可能是微软和Nvidia在整进WSL2的时候没弄好,有些会变成实体档案,造成执行期间系统回报找不到.so档(像这种状况https://github.com/microsoft/WSL/issues/5663),可以直接在Windows路径C:\Windows\System32\lxss\lib(宿主机ubuntu上的路径是/mnt/c/Windows/System32/lxss/lib)下做修改,如果删除档案有权限问题,可以设定trustintaller后再删除https://zhuanlan.zhihu.com/p/108569823。
copy libnvidia-ml.so.1 libnvidia-ml.so.1.1
del libnvidia-ml.so.1
mklink libnvidia-ml.so.1 libnvidia-ml.so.1.1 #libnvidia-ml.so.1链结指向libnvidia-ml.so.1.1实体档案
del libcuda.so
del libcuda.so.1
mklink libcuda.so libcuda.so.1.1
mklink libcuda.so.1 libcuda.so.1.1
(三). 训练环境準备
上述WSL2环境问题确认好后,就可以安心的使用docker建container出来,不过基本上你如果照官方github上面的requirements.txt去安装是没有办法训练的,因为这些环境设定都是建立在当下开发者他的环境状态所列出来需要安装的东西,实际上你若从乾净的ubuntu作业系统安装,一定是会缺东缺西,相信有在玩AI模型训练的一定都知道,克服环境建立的坑是每个AI工程师必备的技能,我这边就简附我使用乾净的ubuntu22.04 docker image从头装到尾有安装的项目,照着安装就可以训练MiniCPM-V 2.6。
#起一个ubuntu容器
docker run -itd --gpus all --name minicpm_py3.10_training -m 32g ubuntu:22.04 bash
apt update && apt upgrade -y
apt install zip -y
apt install vim -y
apt install python3-pip -y
apt-get install wget -y
apt install libgl1-mesa-glx -y
apt-get install -y lsof
apt-get install gdb -y
apt-get install logrotate -y
apt-get install git -y
#ubuntu vi 中文乱码解决
#加上 set encoding=utf-8
echo 'set encoding=utf-8' >> /etc/vim/vimrc
#时区安装
DEBIAN_FRONTEND=noninteractive apt-get install -yq tzdata
TZ=Asia/Taipei
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
dpkg-reconfigure --frontend noninteractive tzdata
#miniconda安装
mkdir -p ~/miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
rm -rf ~/miniconda3/miniconda.sh
~/miniconda3/bin/conda init bash
~/miniconda3/bin/conda init zsh
source ~/.bashrc
conda create -n minicpm_env python=3.10 -y
conda activate minicpm_env
git clone https://github.com/OpenBMB/MiniCPM-V.git
cd MiniCPM-V
#注解掉requirements.txt里的gradio相关套件
pip install -r requirements.txt
pip install bitsandbytes==0.44.1
pip install peft
pip install tensorboard
pip install gguf #转gguf转int4会用
pip install llmcompressor #模型量化使用, 可不用装
#装cuda
conda search -c nvidia cuda-nvcc #查询版本对应
conda install -c nvidia cuda-nvcc==12.1.66 -y #跟着torch版本变动
conda install cuda-toolkit==12.1 -y #torch版本影响deepspeed版本, deepspeed版本影响cuda版本
#装deepspeed compile好的版本
#https://github.com/AlongWY/deepspeed_wheels/releases/tag/v0.14.2 user pre-built deepspeed
wget https://github.com/AlongWY/deepspeed_wheels/releases/download/v0.14.2/deepspeed-0.14.2+cu121torch2.1-cp310-cp310-manylinux_2_24_x86_64.whl
pip install deepspeed-0.14.2+cu121torch2.1-cp310-cp310-manylinux_2_24_x86_64.whl
#验deepspeed有没有安装成功
ds_report #这边都要变成以下这样才算过关
--------------------------------------------------
op name ................ installed .. compatible
--------------------------------------------------
[WARNING] async_io requires the dev libaio .so object and headers but these were not found.
[WARNING] async_io: please install the libaio-dev package with apt
[WARNING] If libaio is already installed (perhaps from source), try setting the CFLAGS and LDFLAGS environment variables to where it can be found.
async_io ............... [YES] ...... [NO]
fused_adam ............. [YES] ...... [OKAY]
cpu_adam ............... [YES] ...... [OKAY]
cpu_adagrad ............ [YES] ...... [OKAY]
cpu_lion ............... [YES] ...... [OKAY]
#清理garbage
apt-get clean
rm -rf /var/lib/apt/lists/*
#清理pip cache
rm -rf ~/.cache
#清理conda缓存目录中的下载的包文件、索引文件和不必要的缓存文件
conda clean --all -y
#包tar档后压缩
docker commit container_id minicpm_training:version5
docker save image_id minicpm_training:version5 | gzip > /tmp/minicpm_training_version5.tar.gz
移转Image到要训练的GPU server使用docker load载入tar档后,产生container的指令记得要加上share memory的设定(--shm-size=2G,大小可以自己决定),因为训练中有用到NCCL套件,没有加的话会报torch.distributed.elastic.multiprocessing.api: [ERROR] failed (exitcode: -7)这种直观看不出来跟share memory有关的错….
(四). 训练资料準备
我们的目的,是要能够输入一张图,请MiniCPM-V回传我们希望取得的栏位,并且是格式化的回传结果,好让我们能够依据格式化的key準确地取得对应的栏位值,若依据官方finetune上的资料sample code,我们可以改成类似像下面这样,让模型用标準json格式回结果:
[
{
"id": "0",
"image": "path/to/image_0.jpg",
"conversations": [
{
"role": "user",
"content": "<image>\n如果这是张高铁票,请回传乘车日期、起站、迄站、票面金额、票号"
},
{
"role": 'assistant",
"content": "{\"乘车日期\":\"2024-04-20\", \"起站\":\"台北\", \"迄站\":\"左营\", \"票面金额\":NT$1490, \"票号\":\"04-2-18-0-094-0498\"}"
}
]
}
]
训练资料每一张图片都做这样的标记格式,我这边使用上每个类别是500张(因为我们是从PaddleOCR转为MiniCPM-V使用,原PaddleOCR官方号称单类别有500张即可有很好的效果)。prompt的撰写上,因为我们不会知道输入的是什么样的凭证,所以我的prompt开头是"如果是xxx",这样的方式可以让模型自己去判断这是什么凭证(实验到后面其实我们也发现模型的确可以针对图片做正确的分类^ ^)。
(四). 模型训练需要注意的参数讲解/修改
官方模型全量finetune的shell档已经写好,路径在这里:
https://github.com/OpenBMB/MiniCPM-o/blob/main/finetune/finetune_ds.sh
但因为2025/01/13官方有改版,我看他们对finetune资料夹下的code都进行了更改使其支援MiniCPM-o,所以我这边列出我网誌练2.6版使用的程式版本连结:
https://github.com/OpenBMB/MiniCPM-o/tree/8464c94a7b76615705e8a41b23ba3eb59de796b7/finetune
我们可以对这个档案进行部分修改,调整部分参数以利我们进行模型finetune,我有调整到的参数简列如下:
- GPUS_PER_NODE:调整GPU使用数量
- MODEL:pretrained model位置(因为公司的GPU Server无法连外网,我将模型先载下来放到local位置)
- DATA:训练资料json档
- EVAL:训练过程中的测试json档
- LLM_TYPE:在训练不同版本模型时需要调整的参数,会影响模型训练时前处理回传的一些物件型态
- tune_vison:调整视觉模块,我是要根据我的凭证辨识场景调整所以要开true
- tune_llm:调整大语言模型块,我要求llm依据我要的格式回给我结果所以要开true
- max_slice_nums:图片前处理时,模型要切成几块作处理,官方号称1344*1344的image切9块已有不错的辨识率,我先不动
- max_steps:最多要练几步,用预设的10000即可
- eval_steps:模型每多少步验证一次,用预设的1000即可
- output_dir:checkpoint模型产出位置
- per_device_train_batch_size:模型训练batchsize,我用NVIDIA RTX 6000 Ada测试,4卡开了cpu offloading后此参数可以开到7,8的话会OOM,但我的应用场景实测出来4的训练效果最好
- save_steps:每几步save出一个checkpoint
- save_total_limit:checkpoint只允许save最后几个
- deepspeed:官方提供ds_config_zero2.json和ds_config_zero3.json两个json设定档,建议显卡记忆体够的话用ds_config_zero2.json,我使用ds_config_zero2.json后发现会OOM,将json档内的cpu offloading打开后降低GPU memory usage即可训练
- 前面我会加一行export CUDA_VISIBLE_DEVICES指定我要用的GPU index。
#!/bin/bash
export CUDA_VISIBLE_DEVICES=0,1,2,3
GPUS_PER_NODE=4
NNODES=1
NODE_RANK=0
MASTER_ADDR=localhost
MASTER_PORT=6001
MODEL="/MiniCPM-V/pretrained_model/MiniCPM-V-2_6"
# or openbmb/MiniCPM-V-2, openbmb/MiniCPM-Llama3-V-2_5
# ATTENTION: specify the path to your training data, which should be a json file consisting of a list of conversations.
# See the section for finetuning in README for more information.
DATA="/minicpm_dataset/train_data_done.json"
EVAL_DATA="/minicpm_dataset/eval_data_done.json"
LLM_TYPE="qwen2" # if use openbmb/MiniCPM-V-2, please set LLM_TYPE=minicpm, if use openbmb/MiniCPM-Llama3-V-2_5, please set LLM_TYPE="llama3"
MODEL_MAX_Length=2048 # if conduct multi-images sft, please set MODEL_MAX_Length=4096
DISTRIBUTED_ARGS="
--nproc_per_node $GPUS_PER_NODE \
--nnodes $NNODES \
--node_rank $NODE_RANK \
--master_addr $MASTER_ADDR \
--master_port $MASTER_PORT
"
torchrun $DISTRIBUTED_ARGS finetune.py \
--model_name_or_path $MODEL \
--llm_type $LLM_TYPE \
--data_path $DATA \
--eval_data_path $EVAL_DATA \
--remove_unused_columns false \
--label_names "labels" \
--prediction_loss_only false \
--bf16 true \
--bf16_full_eval true \
--fp16 false \
--fp16_full_eval false \
--do_train \
--do_eval \
--tune_vision true \
--tune_llm true \
--model_max_length $MODEL_MAX_Length \
--max_slice_nums 9 \
--max_steps 10000 \
--eval_steps 1000 \
--output_dir output/output_minicpmv26 \
--logging_dir output/output_minicpmv26 \
--logging_strategy "steps" \
--per_device_train_batch_size 4 \
--per_device_eval_batch_size 1 \
--gradient_accumulation_steps 1 \
--evaluation_strategy "steps" \
--save_strategy "steps" \
--save_steps 2000 \
--save_total_limit 5 \
--learning_rate 1e-6 \
--weight_decay 0.1 \
--adam_beta2 0.95 \
--warmup_ratio 0.01 \
--lr_scheduler_type "cosine" \
--logging_steps 1 \
--gradient_checkpointing true \
--deepspeed ds_config_zero2.json \
--report_to "tensorboard"
官方的finetune_ds.sh调整完后,我会再写一个nohup的shell档,执行后让他在背景训练写log:
source ~/.zshrc
conda activate minicpm_env
nohup ./finetune_ds.sh &> train.log 2>&1 &
然后训练就可以开始了(V2.6版的忘记截图,贴个V2.0版的代替,基本上是差不多的,差在V2.6 llm_type会显示qwen2)
(五). 训练完毕后的模型使用前调整
模型训练完后的checkpoint内的模型档案,你若直接写code去load的话,会报MiniCPMVTokenizerFast object has no attribute image_processor的错误,看起来是官方在finetune过程中code没有写好导致模型产出时有缺档https://github.com/OpenBMB/MiniCPM-o/issues/408,我这边的解决方法是直接将原pretrained model资料夹中的档案複製过去即可。
https://huggingface.co/openbmb/MiniCPM-V-2_6/blob/main/preprocessor_config.json
https://huggingface.co/openbmb/MiniCPM-V-2_6/blob/main/processing_minicpmv.py
https://huggingface.co/openbmb/MiniCPM-V-2_6/blob/main/image_processing_minicpmv.py
(六). 模型準确率、Transformer架构与vLLM架构推论速度
训练的step中得到的checkpoint模型,原则上要在一定step数以上,模型回给你的结果才会照你的prompt中写的json格式回,太前面step的模型容易不照格式回给你,以我前面写的範例中,我都是直接取用checkpoint-10000的模型来做验证使用,得到的结果都是我要的json格式。
简列我的训练结果如下,我是依凭证的栏位正确率与凭证正确率(单一凭证辨识全对的比率)来做验证,辨识凭证数量基本上都有50张以上,栏位数不一:
栏位正确率 | 凭证正确率 | |
---|---|---|
凭证A | 99.66% | 98% |
凭证B | 98.8% | 94% |
凭证C | 98.57% | 92% |
凭证D | 99.71% | 97.97% |
凭证E | 99% | 94% |
凭证F | 99.65% | 98.29% |
和之前的PaddleOCR正确率比较,凭证正确率基本上都拉到九成以上,这对user来说爽度是很足够的,因为这代表辨识出来的结果几乎都会是对的^ ^。
推论速度依照官方说明使用vllm会最快:
我选用0.6.5版本,官方号称速度提升不少https://news.miracleplus.com/share_link/39977,最后与Transformer架构比较数据如下:
基本上用vLLM让整体推论速度提升12%以上,单张凭证推论速度稳稳的压到3秒以下,凭证推论速度不一是因为有的凭证需要辨识的栏位比较多一点。
Transformer框架推论速度 | vLLM框架(0.6.5)推论速度 | vLLM框架使用后速度提升 | |
---|---|---|---|
凭证A | 2.46 | 2.12 | ↑ 13.8% |
凭证B | 2.235 | 1.916 | ↑ 14.2% |
凭证C | 3.089 | 2.668 | ↑ 13.6% |
凭证D | 2.992 | 2.623 | ↑ 12.3% |
凭证E | 2.354 | 2.035 | ↑ 13.5% |
凭证F | 2.174 | 1.81 | ↑ 16.7% |
最后,我和管GPU机器的同事有做进一步的速度测试,发现CPU时脉会大大影响推论的速度,我们在猜应该是跟GPU推论前程式会做图片切割前处理的关係,这段使用的是CPU,未来若公司可以採购推论用的机器,也许速度上可以进一步的提升。