原文:ray集群摆设vllm的折磨-阿里云开发者社区
简介: 概括如下:在构建一个兼容多种LLM推理框架的平台时,开发者选择了Ray分布式框架,以办理资源管理和适配标题。然而,在实验集成vllm时遇到寻衅,由于vllm内部自管理Ray集群,与原有操持辩论。颠末一系列实验,包罗调解资源分配、修改vllm源码和利用Ray摆设的`placement_group_bundles`特性,终极实现了兼容,但依靠于非官方支持的办理方案。在面对vllm新版本和Ray摆设的`reconfigure`方法标题时,又需权衡和调解实现方式。只管面对困难,开发者以为利用Ray作为同一底层仍具有潜力。
ray作为开源的分布式框架,我不停对其抱有好感。以是在实验搭建一个LLM inference平台的时间我想到了ray。
这个想法是在客岁下半年的时间萌发的,其时开源界已经有许多LLM inference的框架,好比:huggingface transformer(包罗accelerate)包,deepspeed-inference/deepspeed-FastGen(似乎现在做了集成,改名为deepspeed-MII),另有GGUF格式的inference,以及本日的主角vllm。 但是缺乏一个可以大概兼容上述主流框架的平台,这个平台底层可以大概为负载分配盘算资源,向上可以适配多种inference框架。如许可以大概最大满意用户的差别需求,如:利用差别inference框架来运行LLM模子(好比新出的模子,vllm等框架还没有适配,那得利用根本的transformer包,大概比力差别框架运行同一个模子的差别等等)。
我开始到的是利用k8s,但是其时发现纵然是最底子的包罗hg transformer的镜像都凌驾7g(现在大概会有改观),这个劝退了我,以是我转投ray(大概是一个错误)。
ray的根本原理是:以node为单位构成ray cluster,inference代码以历程的方式跑在node上,如许可以共享lib,部门克制了上面提到k8s方案的标题。做资源分配的时间创建placegroup(PG), PG中包罗bundles, 好比{“CPU”: 1, “GPU”: 4} 就是一个bundle,inference代码跑在这种被分配的资源中,然后根据node的capacity举行调理(雷同k8s schedule)。
在最初的实现中,这个机制工作的很好:
- 分析model设置,如model ID啊,必要的资源啊,是不是要做张量并行啊,autoscale设置(ray支持autoscale和serverless),加载model和推理model用到的参数等等
- 根据资源需求和并行参数创建PG/bundles
- 将inference代码运行在PG/bundles里,然后做后续的工作,如利用指定的inference框架加载模子啊,等等
这套做法在适配hg transformer包,llama.cpp, 乃至deepspeed inference的时间够工作的很好,但是在vllm的时间遇到了标题,我想把他称之为vllm第一次折磨。
vllm的实现中有一点很故意思,假如设置了tensor_parallel > 1, 那么默认启动/毗连ray cluster,利用ray作为张量并行的底层平台(ray version <= 0.4.1举动)。这就给我们的实现带来了很大的困难:
- 我的实现:根据resource需求创建PG -> inference框架跑在PG的bundle中
- vllm的实现: 启动vllm的engine(vllm叫法)-> engine根据张量并行和资源要求接洽/创建 ray cluster,并创建PG,然后跑inference代码
抵牾点很显着,vllm将ray置于其框架之下,而我们的实现是把框架作为ray的一个负载,这一上一下就为集成带来了很大的困难。
幸亏这个标题终极得到了办理,方案是vllm engine可以担当一个已经存在的PG,如许克制了vllm本身创建,维持了我们方案的同等性,固然也付出了很大的调研时间,但终极是办理了(vllm version 0.2.0 - 0.2.6)
固然标题得到了办理,但是我内心仍旧很不安,缘故原由很简单:我的办理方案并不是vllm官方支持的,只是通过研读源码,自行找到的办理方案。在社区未来的升级中大概率会被粉碎掉!
根据墨菲定律,标题来的很快!在本年早些时间Qwen1.5架构出来以后,我发现之前集成的vllm版本(v0.2.6)并未适配Qwen1.5,无奈之下,开始对其时最新的vllm 0.4.1举行升级。
我愿把这次集成称为vllm第二次折磨。
不出所料,标题出现了!
标题还比力棘手,在先容标题之前,我先讲下我本来的实现:
如上图,
- 表面的虚线代表ray cluster
- Driver(ray的说法)代码会创建一个ray deployment,这个deployment紧张作用是利用fastapi做一个rest的实现,后期对外提供rest服务。注意,这个deployment没有分配GPU,默认分配一个CPU.
- 在Rest wrapper这个ray deployment中bind(ray说法)别的一个ray deployment:Worker wrapper,这个deployment的紧张作用是创建PG,并将模子加载,推理等代码跑在创建的worker(bundles)中。注意,这个deployment也没有分配GPU资源。
- Workers, 是ray actor,根据用户设置的资源需求和张量并行的设置(worker的数量)分配了相应的GPU。
在vllm的适配中,vllm engine的启动是在Worker wrapper中完成的,创建完PG后交给vllm engine,这个逻辑在vllm version 0.2.0 - 0.2.6工作的很好,但是在vllm 0.4.1中遇到了新的贫困:
新版的vllm在启动engine的时间做了大量的工作,必要GPU/cuda的支持,好比决定用谁人attention framework(xformers, flash attention等),详见vllm attention实现。 这就意味着得为worker wrapper这个本来不必要GPU的ray deployment分配GPU资源,这在我看来是不可担当的。
为了办理这个标题,我做了如下探索:
- 为worker wrapper分配0.1GPU, 这会连带某一个worker只会得到0.9个GPU,但是遭到了失败,缘故原由是在vllm的实现中,worker之间是通过nccl举行通讯的,nccl要求完备的GPU。
- 研究了vllm源码(vllm ray实现源码),说实话,这个实现给我带来了很大的困扰,我也在社区提了issus,渴望能得到其时的操持文档,但是并未得到有代价的复兴(吐槽vllm社区哈)。终极我通过继承社区的实现修改了部门逻辑,原理是让启动engine时部门必要GPU的代码跑在worker中,由于这些代码是一次性实验,以是不会影响终极worker的实验。
固然标题办理了,但是不安更严厉了,这次的办理方案更加的hack,完全不是社区支持的。
带着如许的担心,我开始探求其他办理方案,荣幸的是,我找到了ray社区给出的方案:ray给出的方案, 不幸的是这个方案在vllm最新版本中并不工作,我无奈提了个pr去fix,一周多还没有merge,固然这是别的一个话题。
这个方案中给出了新的办理方法:不去创建PG, 利用ray deployment的placement_group_bundles参数,为worker wrapper声明(非分配)充足的资源,在我们的情况中是[{“CPU”: 1}, {“CPU”: 1, “GPU”: 1}, {“CPU”: 1, “GPU”: 1}],这是tensor_parallel == 2的情况。
这是个很风趣的方案,可以办理我的困难。
但实践过程充满了妨害:我在实现中利用了ray deployment的reconfigure方法来利用客户化数据(model的各种参数等),但是厥后发现只要deployment中有reconfigure方法,那么placement_group_bundles的设置就不见效,我没有深入研究ray deployment的实现,一度以为reconfigure方法被调用的时间点大概相应包罗GPU资源的PG还未创建,但是厥后发现,只要reconfigure方法存在,哪怕是空方法,那么placement_group_bundles就不见效,已经提出issue到ray社区,仍未得到复兴。
但是这已经不影响我的实现了,放弃利用reconfigure就可以了。
这个称为vllm第2.5次折磨!
总结一下,利用ray作为兼容多个inference 框架的底层大概是个有代价的想法,随着inference的继承发展,大概会越来越有吸引力,但是难度也存在,必要不绝的办理标题,但这也是步伐员的兴趣所在。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |