From 8a4f4a0c452e05c498362c6e43ca30055c12dfdb Mon Sep 17 00:00:00 2001 From: zhihang Date: Thu, 11 Sep 2025 14:00:37 +0800 Subject: [PATCH 1/3] upgrade vllm to 0.10.1 Signed-off-by: zhihang --- AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile | 25 ++++++ AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile | 22 +++++ AI/vllm-cpu/README.md | 3 +- AI/vllm-cpu/doc/image-info.yml | 85 ++++++++++++++++++++ AI/vllm-cpu/doc/picture/logo.png | Bin 0 -> 81610 bytes AI/vllm-cpu/meta.yml | 6 ++ 6 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile create mode 100644 AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile create mode 100644 AI/vllm-cpu/doc/image-info.yml create mode 100644 AI/vllm-cpu/doc/picture/logo.png diff --git a/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile b/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile new file mode 100644 index 00000000..cb289ea4 --- /dev/null +++ b/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile @@ -0,0 +1,25 @@ +ARG BASE=openeuler/openeuler:22.03-lts-sp4 +ARG VERSION=v0.10.1 + +FROM ${BASE} + +ARG VERSION + +RUN yum update -y && \ + yum install -y make gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ python python-pip python3-devel git vim wget net-tools numactl-devel && \ + rm -rf /var/cache/yum + +ENV PATH=/opt/openEuler/gcc-toolset-12/root/usr/bin/:$PATH +ENV LD_LIBRARY_PATH=/opt/openEuler/gcc-toolset-12/root/usr/lib64/:$LD_LIBRARY_PATH + +WORKDIR /workspace + +RUN git clone -b ${VERSION} https://github.com/vllm-project/vllm.git + +WORKDIR /workspace/vllm + +RUN pip install "cmake>=3.26" wheel packaging ninja "setuptools-scm>=8" numpy + +RUN VLLM_TARGET_DEVICE="cpu" pip install -e . --extra-index-url https://download.pytorch.org/whl/cpu + +ENTRYPOINT ["python", "-m", "vllm.entrypoints.openai.api_server"] diff --git a/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile b/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile new file mode 100644 index 00000000..e4337c40 --- /dev/null +++ b/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile @@ -0,0 +1,22 @@ +ARG BASE=openeuler/openeuler:24.03-lts +ARG VERSION=v0.10.1 + +FROM ${BASE} + +ARG VERSION + +RUN yum update -y && \ + yum install -y make gcc gcc-c++ python python-pip python3-devel git vim wget net-tools numactl-devel && \ + rm -rf /var/cache/yum + +WORKDIR /workspace + +RUN git clone -b ${VERSION} https://github.com/vllm-project/vllm.git + +WORKDIR /workspace/vllm + +RUN pip install "cmake>=3.26" wheel packaging ninja "setuptools-scm>=8" numpy + +RUN VLLM_TARGET_DEVICE="cpu" pip install -e . --extra-index-url https://download.pytorch.org/whl/cpu + +ENTRYPOINT ["python", "-m", "vllm.entrypoints.openai.api_server"] diff --git a/AI/vllm-cpu/README.md b/AI/vllm-cpu/README.md index 0f2b7e30..9661ea1e 100644 --- a/AI/vllm-cpu/README.md +++ b/AI/vllm-cpu/README.md @@ -44,7 +44,8 @@ The tag of each vLLM docker image is consist of the version of vLLM and the vers |[0.9.0-oe2403lts](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.9.0/24.03-lts/Dockerfile)| vLLM 0.9.0 on openEuler 24.03-LTS | amd64, arm64 | |[0.9.1-oe2203sp4](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.9.1/22.03-lts-sp4/Dockerfile)| vLLM 0.9.1 on openEuler 22.03-LTS-SP4 | amd64, arm64 | |[0.9.1-oe2403lts](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.9.1/24.03-lts/Dockerfile)| vLLM 0.9.1 on openEuler 24.03-LTS | amd64, arm64 | - +|[0.10.1-oe2203sp4](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile)| vLLM 0.10.1 on openEuler 22.03-LTS-SP4 | amd64, arm64 | +|[0.10.1-oe2403lts](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile)| vLLM 0.10.1 on openEuler 24.03-LTS | amd64, arm64 | # Usage diff --git a/AI/vllm-cpu/doc/image-info.yml b/AI/vllm-cpu/doc/image-info.yml new file mode 100644 index 00000000..ffdfd48a --- /dev/null +++ b/AI/vllm-cpu/doc/image-info.yml @@ -0,0 +1,85 @@ +name: vllm-cpu +category: ai +description: vLLM是一个高性能的、可扩展的、易于使用的用于大语言模型(LLM)推理的库。它支持CPU和GPU推理,并且可以与流行的深度学习框架(如PyTorch和TensorFlow)无缝集成。 +environment: | + 本应用在Docker环境中运行,安装Docker执行如下命令 + ``` + yum install -y docker + ``` +tags: | + vLLM镜像的Tag由其版本信息和基础镜像版本信息组成,详细内容如下 + + | Tags | Currently | Architectures| + |--|--|--| + |[0.6.3-oe2403lts](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.6.3/24.03-lts/Dockerfile)| vLLM 0.6.3 on openEuler 24.03-LTS | amd64 | + |[0.8.3-oe2203sp4](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.8.3/22.03-lts-sp4/Dockerfile)| vLLM 0.8.3 on openEuler 22.03-LTS-SP4 | amd64, arm64 | + |[0.8.3-oe2403lts](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.8.3/24.03-lts/Dockerfile)| vLLM 0.8.3 on openEuler 24.03-LTS | amd64, arm64 | + |[0.8.4-oe2203sp4](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.8.4/22.03-lts-sp4/Dockerfile)| vLLM 0.8.4 on openEuler 22.03-LTS-SP4 | amd64 | + |[0.8.4-oe2403lts](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.8.4/24.03-lts/Dockerfile)| vLLM 0.8.4 on openEuler 24.03-LTS | amd64 | + |[0.8.5-oe2203sp4](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.8.5/22.03-lts-sp4/Dockerfile)| vLLM 0.8.5 on openEuler 22.03-LTS-SP4 | amd64, arm64 | + |[0.8.5-oe2403lts](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.8.5/24.03-lts/Dockerfile)| vLLM 0.8.5 on openEuler 24.03-LTS | amd64, arm64 | + |[0.9.0-oe2203sp4](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.9.0/22.03-lts-sp4/Dockerfile)| vLLM 0.9.0 on openEuler 22.03-LTS-SP4 | amd64, arm64 | + |[0.9.0-oe2403lts](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.9.0/24.03-lts/Dockerfile)| vLLM 0.9.0 on openEuler 24.03-LTS | amd64, arm64 | + |[0.9.1-oe2203sp4](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.9.1/22.03-lts-sp4/Dockerfile)| vLLM 0.9.1 on openEuler 22.03-LTS-SP4 | amd64, arm64 | + |[0.9.1-oe2403lts](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.9.1/24.03-lts/Dockerfile)| vLLM 0.9.1 on openEuler 24.03-LTS | amd64, arm64 | + |[0.10.1-oe2203sp4](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile)| vLLM 0.10.1 on openEuler 22.03-LTS-SP4 | amd64, arm64 | + |[0.10.1-oe2403lts](https://gitee.com/openeuler/openeuler-docker-images/blob/master/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile)| vLLM 0.10.1 on openEuler 24.03-LTS | amd64, arm64 | + +download: | + 拉取镜像到本地 + ``` + docker pull openeuler/vllm-cpu:{Tag} + ``` + +usage: | + - 启动容器 + ``` + docker run \ + --name my-vllm \ + -it openeuler/vllm-cpu:{Tag} bash + ``` + 用户可根据自身需求选择对应的硬件设备{device}、对应版本的{Tag}以及容器启动的选项。 + + - 参数说明 + | 配置项 | 描述 | + |--|--| + | `--name my-vllm` | 容器名称。| + | `-it` | 以交互模式启动容器。 | + | `openeuler/vllm-cpu:{Tag}` | 指定要运行的镜像为 `openeuler/vllm-cpu`,其中` {Tag}` 是需要替换的镜像标签。 | + + - 容器测试 + + 查看运行日志 + ``` + docker logs -f my-vllm + ``` + + 使用shell交互 + ``` + docker exec -it my-vllm /bin/bash + ``` + +license: BSD 3-Clause license +similar_packages: + - Ollama: Ollama是一个用于在本地运行大型语言模型(LLM)的工具,旨在简化模型的部署和管理。它支持多种LLM,并提供了一个统一的接口来与这些模型进行交互。 + - ONNX Runtime: ONNX Runtime是一个高性能的推理引擎,用于运行ONNX(Open Neural Network Exchange)格式的机器学习模型。ONNX是一个开放的生态系统,旨在促进不同深度学习框架之间的互操作性。 +dependency: + - transformers + - datasets + - torch + - sentencepiece + - protobuf + - numpy + - psutil + - aiohttp + - aiofiles + - fastapi + - uvicorn + +homepage: https://github.com/vllm-project/vllm +upstream: + version_url: vllm-project/vllm + backend: GitHub + version_scheme: RPM + version_filter: rc + version_prefix: v \ No newline at end of file diff --git a/AI/vllm-cpu/doc/picture/logo.png b/AI/vllm-cpu/doc/picture/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e1c94e01947825f454087061c81d7a068f8dfe6a GIT binary patch literal 81610 zcmeEvcRben`#*P-(NKsG8n$SV8Fxpe?2O2c%8cwi?uLrcx~;52_TFXO4P+}M60-Lu z+wXecw@&92=kxvZ_ebaP=sfNm_v`%{*Y&)f*Ymnw?{iN{L3$en0|gNg(YAAEPbm`- zk?Ru?k))ArhM#yuTVaTZh&fE8q?F90q@^s)Ev;3qUoyOM^0KAD6=mtaj);f|6A^Jf zG}PBuKFiDb{?aae{rA;8Tol$0%6ISHSJwA&3(T#Qw^LZG5q?+BE7V?1Ah;?z(gX%z%tH&_Iow9e*NYUnTg{-XoL60JyBoIv& zdOeGYxy^phos~>RnMVelW#fMG%K59#XYSoNa5!3-R($Hwj4jRmt@q{V>CxY|pI;WC zVhX=+U_@m==1KMRz-wGb@e>TDXUAVv(SevtnC+W3t*YJ%3fZ^mrl-WFw?!i5F{iI6 z8PW&e-$PF}L9A6HW0$B;`~Y@N_=?84tMc+h-0+!~P5ea-EhCdAOhlmIjiTd#q za{b6nKR%PBA^%Z7RO1s75t``SsgtUX#KT`lEE{L$w~X&l3#?+(dXvGH7sPwu3$t7x zn@#DK`gf-u@1d?%wO}58y>fe*)+KKhBxF>q=>PFSc6Yy~ z^=;Ju>33ngITI^hv)x+4(;Y1V0{Z^7cQQOgOYZ zoBY$n{#f!)m;VD7f8**OxcCW{f8gQ|T&x%E|G>o`xcG?@f77r(aPbE&{=miG?y%m6 zKkVWsZv26ZKXCB}F4jYdKkVWsO8mV)f8gQ|T>OEHzujTI4}aLjPu%ze7k}X54_vH= z5`WmmPn7t3fBwM5AGr7f7k|6MdLRC4<-Jvi=Qa*_x}8Wi$8Gj z2QL10hxI=EVHZDf;}2Z?fr~$Iu^vkNVHZD9;_vV+o$`Z{9iOCsv9}oGNJ~1Mn5H8a?7<<@@PNwRgM(;Q@vR`#tQbgzFBtZ z9~_h^p0BnXU1e`)gWo(!x^zON&gWuea>Vkmkx5SlmeRE;kerG&%@spCwd!(c^+@>7 z7Wl|kR9{V)tjF?@o=Rpj?{`)ahxP@@iq#2!k8an5E~L4imAhl?RZwX0n1MwC{JriR zu}7bsvWJP$>hhR}Vln(X@Iv=ju(bX(TtkEELZ#lyBhA%m?mM{lmD$|skFxyOsEazg zSe0amC2yoXX?kJuqvIW8PbsIUNU4|2*f@neDe^jMrHH2$YkU_uwWGVn9dys6?GexU zV0?L8)&C$YE(i4`=NffUMZo8JSdo$_F>%sIonSBc{BucvLm~2^k!r5v=8lgOU1f8;ms$q&eWJP5<}_Zu%v zR`O?x;T|L3ihKeM{V@f{<&l$G&)!fZ3H!!Z7RO>$VinX3=~ZCnCYbs8`G%$@^?^Ox zq>(Qjfu#gJ<^HiXKU9lzkKaUY4B#f=4nsg+Y{-V+N9zZp zs;?fib8z6F;;Mj^!&amlmVLa#;vV$(EOx^zW@b#nHyj0Kk=yPrrjvL5+1f0~r)Or= zEZ8?8vp_GxELw~P&izC##4`T1ttT(&gLvG#cc)si&D38QISM0Z_e2j(l(^(zyz!+M^c9jE^X5k>ImTL`F(VDnESSFg&$Ywqs#t zD4v#LW}Q&g|W#_scQ-oCdglG!Dz7?m8&P!H;VuA&dT!YZ)v5^!P)Rb7euBo5N~|tT35ben_Ux=a$1_ei7=v+;0iH-45HLQVMG`vQa|PsArcGyQA~=qG{_WGPr?)^a*a1{JcZMw z67$`Ur$=9nU9c53+{vmWfC&!|f1Vx9f_#S)1Ct=!uW0?o6MbN!>{h35|yb-bY7$;FRNM*asGgu?CyQ z4i(wTZs?kEF`kOA6MC{4L(mrZ&=eIFl^@o}ihp_lJUx4~USQ*=%TO?hSRdRgW}oyZ zbB{L>riRkIC5ub&X?2az^G)~-h=DP zN|q5LUs2KlI~r_DF5kce06wt0gl+qk7REeQwc>-fN_nFDNWJddsjq%2B-Va+JMz8A zEF@wSiu!JB&x0IkR$ZkF+pZZvB&0SbO$Bf`=2El;`3Cv~faIW6?F%G;t?y5&f9ac> z^SUhz#A1U=s7T0cb@eY_KB!aZoIT~+kN=X)Ay!Yd!J&Hb^#?#^sk;XEO=iaRyI3FG z!?m_*n+h-li+_>Ad!;U{V&*=Q&_q@w?%tc zH#VZ)6C&?{j{4LLs~J^zXoDKKV~UWa#YPkGM3<9-@dSVo$x7Uwh52iByt_voKSQp8 zARX+n4(#E`qiLoMM&^CAiKL`B}FbAI(lV|>84$sN6+(|C+-0Fc#pO_M| zty{N7U(L)9%5~m>-+YZMPohuH;|m^cV2;R2@1kzryg4vC^5wL-ydnu1&DoC0p2~sb z+%|3{X-zyjBp}w%!(M%IBdey0i^rAt&>{Y4Dq5IMPNk8A>#crzTaeDD#|>Fa+Cex@ zHY=xN8=8bCdMD|^;$l6R@=mRKYGM>ARZw`iLNZYR9sWD-|3VY-P^#5#>{?Xs)jC@9 zZA^eS6T)uAfi&P%wj(XslLAR9$R=`P0c7G+WHa&myZ&k@$psjE8_bW>E##z9vnr|J zNzKC4Yvho?%Gg*vvDl=(ja>^O_hF!au%CehvzSA{p(;>QQ8;90`!iRMllZfvBe$Z;{8uv*j6vcSl{Qa`r7RXU}F-1j127=Ly$aLe9kZ70sNq@r$U=}EtBwU4;`y^N6 z`8~_Y8?-y>6(!{j4Gjg=596QNjT~fPmd!?62=lV0{hViIn9?V5p9s@QHvRp3EHHph zfoN*{9Kf?K#H2P||F1a=w--x>Nw~c%B4XzNOY))Pe-S3;@X6NM5Fai$AY6z(8%{58 zopOqiXHY6CDkhGOd1t5@vB(hKtT4nat-4Jc4&jMrN7>le#K*>RJT`LSBu14`e|~9a z_R^~B%mhRIPUL&4nqW>Jo6Lm&V=WNrRc~$6|&sk$h{vOnTGa-`WafS5~~Yo!xkA zuS@G28*_erX*X13x%`+2LqP^0NFjHL1lb49OfdCeOU1GEcN7m{vb*wZ2b5c2fJdeU z!Qd|xu9M{)1BKt)cz#Sn6QW3CXUMj5|2YkPeb(xlnzs355Ab>e%*x8jE{9Y+vybzJ zX{cFzWcrV3`0Nt)SaEHE?Du)wkUX5HddHjFlqRr2CD)XU@H@%~JKCb1eeyqcbQD=V zgn+T7Pm<(RoX>DCnuKY1a{mSwp-Hfg!n1(Pa*W#;8GK*wC;S~|y`@!>{JgwWZ z!2kfu0KyWaJPy`dc4_3`{Pv1{gmf}snP~?Bu}2_*G!2aITX*t=c|B3+_?&Jy5V5*s zG_dgLFyv_uaF}8NPmejA-=9V5-SUF#0{)}rV3e>RL56`cKHa8 z6(=#~o;`R=h`a`&taAo3jPq81M)!t~&CnJ{51gM9z6LSZLdj(@k=d)5U;V1{G z3Jm|lExg$fv{Y17Ob_|EjTklH!(Vh3Ld!k^Eu`Q9WBQ!?sSWkYenf_jPy79% zM&C}>>ns@fr-9<^nzHg7i2*ZLrwP`%?ouASLUckP{rM3?XcWolq3a-|W&zD}@u*kF z&mDadJcGh|XUqDgfS(mMY;Li< zqWHwAVCgzBSQ0m~`OS%f8*je;C5%v;qv1Epg&Os5JP`$kJIQPn^ers-1Q~p51eI`) z0VB0=DOvdVdx)5r*JT4wfceKg!wohj)*q`CS9x1bCuz;&*|=bJ3lgVp{xpZNHrth@ z`K29v{r8HOdid*scj?rPX5r5irD4AzS|L_LW7w5JWLB{`ubo*Y>CkkPrjkA3L zGZ=r#6-VdM{Jx5oq9QnWB}#}5n%bHBHg@=TM8df;l7N3M4}%oFI^$`ig%ZvA+ww!S?l;#3q*U@xTVg3fnEEa`)Bbbfw5 z9w1_9=Ahc}@! zPuS!U?Zp#Ff?4R|kYXfyAFV^GiIGlCC0$wSlZ=&ScIqDDpQA;bgGL#G+k>X(TpI>A zv^xs4YIDtOQ#JQ30proY%mpMR_1@HE%SDQ#BHU&#I`@S+RMcND4O{7#mXra`XI&cW zh!-@nq+s;D-r*aklAP%{sU0Vtd;)XqB+sy1?(&yZ0N&or(oF)HQ2*E%o$XTTa`9vZ z&j7&ricnE!AmUR02OUv_qF}Dm2dTV>gliNpYU(G`bMd-g@Zz(%i)K>n$v;%cqME zpd$~V01ObyeyBF#jg+qQK+N=8mX$P$s2~g+Ts9SufD%E*M;jjExIQLO&s}7>V~eEY zIHTFp_J|v5U6n%4SJ!yFaAsfN$ZLP`$+ON~zCsnBauBYlWQJI>Uh%h$Em@B;>y3J9 z!DK~~-gx2|8Imr!&3(JmKL3)Rij|5E&ywAjotKDd6J5XEru*pcvDD=)e+3alRJGs` zTfUo#ZfGL7Mle()jB#lCcrt>m_L{! zs1gnK%$C}ywC*+|XpRZORbYAQBUYwkHLTg}Ho|nt;YSX9PJAz-8-b59P57^V*ny@#^U}Ca4X}_eJQf+~i)mh17VC z8P%vd{uQ&>8RkCWqxU3Q>l!j$oDeBVT2cJBrVY1(7^O#^ zbTQNGof}C=_0_?Ff&5xAS05tG7V^32#87DQ$a`(C`{6$D71Pg1bv4TIA4I~>ePYd7~V*yb++kLe&@i%W5?3M?h{NG9!x{yRO zqI9zRvEnDQel~^0Pg<5Sm4W>H=@nnd8?^LcBYk~+8yUYb)~^n#7t46ey=5type;uD z7$yVRf|1hcjm7Qv=k=EtW<s;ZNz_E`-E}NG6DCJ$W2ZlHDluitbM{DDlpMIr@d_1V~we{0Q=M<;N5W za$8j-gM-w`KI_i@y+v26LmC=;B)`xNC`^Nhi@ED5S$@FObln()f12Pf$Ju71dPDyc z7ozS3N(_R0R}bpXM@luSxQDozp{Dw$mPHq%?u|(fDtau`Prsq$Z(Wry!tZGefEag) zpvlG{RwshF!|cqNEfG^dGXO>zR!0bME37_C8 z5d(rzXg}Xcm@;P7a7>{%iM#gn2g%bX1!>%dUp=Cim%E?-rHg)i_*C5~bM!OgCHvL; zmmT_s-M)YQ{=VIsanV<^GY8YTIp( zIFxuW6~&BL4{0VnO1a>pY@-EJ3iyRQpeEj?A#(BTm5tHIl&kLJ$6eU3noLG?pK~qs zmVn)zaPj0Jq2L{VN3HmdPS5qcKE^Uo!eO-4*vxEk_FO8mE3BC)hP0!vYNWG`e5 z>K!SsM!o&~{1y~K(wi?NYtk++FYl?;d`V);qr{B`Yog5#J17<9&mt)SM;`d>eheNd z&cV=+ZfS2kGS%Eobj*B0hM7;-Fd{JB1I9HuOq>E0K3rz41S5;bk`*xzOJ29ku^~{_ zw-ojBB0h6j8NKNOd!YQs4Ur8~O4bUA(s?JQXD~80%)O##vU!vCKBdE$p2|SFq|VGh zt@$aN*EdLwc3i)WpwCgRNMfGHmF$1_FZ|}5XhV`03SkTmtya>8?6vQcSX{?Xnty#M zc%WJ4G5Q*5n`4(R67Q~Yl-KnG{<+9KJ$^`Pk1Spu^V%OtY{n^Lu(9iqtnex|7hb8N zFTT2P>^+gBs{Lzg2%+ib%}2L-(8Mj}=No_6&x|biffTXFv6^qsx$kX=no6=5O8$bw z7KJmPG!-7sr}K!dAgm=gRf?G8%mJiZVexwhqo?FzbM5oVzSx_{K$9G>0Ul-v`!|fo z=xWm4eA*gQA{i1GowSUi8F^ZDQ0#H9!cDy4=th!PVD&e*ep}T;DOtNk{ zIQyF2sv;Yoy)!wlW>%c8$`$+YEzFLrnfbDzIAaoE$9utSqxS4q|Bh(d`3cfTkTJ%u zforwTj&IC>(fW5$P1-i{OLJwC%m%hc-s-x~_kbQDeZ)uI?h=v=&_GF@*L*pa&i(B+ zp?8hydTt9QsR(Ogl?E5E&I*#*IKnqT!o*kJDI3TqzkSz9_`*{5 zje;+UTk*s(p03UlyTJB{^*77>VF#>*C?q}8wkn|=kUvZsd}47pGu`F;D9z>lq^NAV zI04-g({)nW5u68(Eddj}`_$qk7h=80_s?*Hg+^PCB4XbL54ii{#S4v$%jEY?l2r6q zeY@kwP-v|3jlvifkE zE=I6WwL2T)T>t2(!fC!otN?`|+iB!mUrF|=ZOsb{3p--dTUFI_=n`U|^hKVVlfFI8 z$6N0DPSwGPs;;h1H~#S4GIXMA0EI1m0i73_sZX}E zP8@(qTk~`%F1GR|zgd4wWNT)q^G0&M7_?-W%sf4O^OzcQb&kjC%GRrVS5Q*ab(bA0 z25wOD-EGb^iV*$Afz0)NHq2Feb1UIKw&~^2@H?Oz%qXqKVtwM6bJt6%1~ccOwP)pbbwp|07-*rv-(yo7d6H@zdh8zjr zK%y`5ORbRZ*2uL83u|4;TLDM;R$GW#t&Frqkx=kQ5+{yZ5)*ASRU*tFrCfx>3HOEi zhzlMaOul)b*En|G4aZm^9N-twhTt2lY_*uqN zJ*eoO$-uHBBQ!|C2A+8GcY_B#Ix1_!9+ppNagin7OCfF>|Zo{AI7hE&XjqN-c| zs*d?=qd%UWDqg!?<0fVPuR;5=P6y=I_b+B%y;68Tq*u?W^@}$xkE!UL*W?Gur)OtN zL4JSyhQekU=mq3YM;uan~~{h6d23A zb70@v=GoZPMA!4!{|KHw{A;xtyhzO9jnxZm6$0Y1We0Oor8fJ%!w-<29>dj@7yf20wSV~Q&AnZCulww#?+i&%Iu<}ywOpN1|@8cZI zam0y}C(9tI-U(XF(%al>?)EH5*nSDYldSr5N!@C$-4CTZ-#WIL} zzn~uKGFVh$xOoSYFcs9pylW*_#kqYou+UN2rTQS^Hbfqx>_y^)^&)tAzy!ct2j zv))q*$JMishncr=mqB~zN}c1(Ky1VrJ-zk_LvG2e++2^LY`Wi0h?kQ0V#dMBfhM-^ z*=9{=daQ13N6qX4&==|)$!$+*vW*XqjgRNr&956e$i#+krT2v_sBup40Wkrz9-PE< zx%GUWyTIk1{gTGN;G$of<@d9`anBR^jlJLA*--}l>-1m0ezod+ckfuK$+c^~74}Wr ze+_bIT@s6z125*-AcY!Ne{Al z@SXHte2_HtU)cY{J3pv%m-RX*NSKay`>7}Da+Q5(8+<0mIAwzLF<615pSgW-;-*my z{O>gWjk)jBJay6@(OJ$6Hg0mi#6PdFlf;W74S?Pe3QJxNDt=L8#j7h!>ahaI)Z+rc zK26Ut+#!teJ{vvIZAcvP<)U}-MJ?~uv3YBz;dqPuYWbL;|4g-QIKL2k`#nWypYU&_1h*@H>gLIsj2G-;%H;>Rs~Ju z0{U)W-tw&NB5n^V)lJoJwWx@uxLMQB?M`i;HkLZPc|z;`KhOW{ zV>HALU~|IqTro!jD-6FuhHEuIpg&CVJeEc?X^W0x4zjDTlyOHEBB_)M7P${q#$Rcx( zbv~a>aI^+W&uvBxX-C#Ly+e5fdQ7(D5AMPn##|1Zu%(ORS`nK@L%$Ydy)<@cdBUGj zW@2%4;bhkF?`0w*h4-jUaWV&Y{d%^Swe@R4MUd3*zWVtu)4)WR5lb=^yZ3>TYkd6e z4rxWjNxIWMo>O1P+=UP#zx$c0AmZm}EFh2?`NzX+2xLz>%feSyEUDtXno~rRI-KIM zw>`{SAS7gSMDD<4w3gPFj*}@r0OD`dIm%b};ls|U-s(z6+HA$*49b9;XhBjx7D;Ao z*$&a7-EqUE>hp4+2n9SZM0$u*UdxX$t>jF@TxB2WWG2+jWGAW?dmd}$3cYw&Q!Y)- zk>WbnFF8jYO!6zzickfKIap-neB;9im6*A~WrQHyV95?0E4xrKWU z%-vhdvd}J4wgzDiM3_tpW1J|DFXh^TbxHkZ0}QJZW9DW;l*Q8vnU-TpFF2RKGrULc zxTL@TA<-}3!ODSxn?Jr4QDl2>Qi3RQokjf)A6z(L;kl4RzpzcjUpr0zByilm0+}A< zf#_^-A2qE8$F=8~k~%L|q)#L(FPYkLF*{{46}tH<+L>xu%3TwC7~2JTH-z-I97B3H==e3wrOCizUUZBMzJg&&X^czA ziJKrC5~hKC8e5Ux6PD^wpgAKW;y3$(qon5CiF@U$Mb{cXetbmF@vG;s0)0VbMG&m9 zfRY!=Hti5s%1qy;&4dBrhBo%|Eg7Eb2nio~v~@6oOq*%yJOx>O9RwrCVwzGd1Z7du{4z@3AQEi>Ay@P`4o=8%{OE#pTA>F30W^lV{)?efWD+@yq zH~s!l~Pza?5T3p-ACr0R_*$j!MAgBM@EeQ05U)Wh}uD1^dv#gxLrVHynvOZSP zf6uY2-Dw$v0a>;K9|yM^!y`X04>njMN!bzir8yOjB|?j#7i6Gj^csJy5rt{We*;pq zSUaVt-|4cvm3IffeEC9c_?z95OmZSTNjyNUF=S;*a`hN;zazoVB+Y=V;Cq|P1YEGA zjrx3x`%6p9^U1lB1XG}o2XuH?k?&8y|FhU%;3!^ZB&mFB&&16`hYlTq_VP@>Z%B^! zw|62RSZh%T#&vQ?&YugHWwN^#qs+zZI{x~+zoBO*d6IU1hU4jom`<_LyaO-ff~^A* z74W!*xeVD?`I-G|Mnpq7ETZJMS{Ng_VkO1p-X7L@YRlPV8|7Leqhhy;fTneHRnBl6 zwCww+Pao!Shp50YfIbFQPWBg|OD?9FZM?3U-VS@2K7ods0#JylKU zY4=3G{RNdQ97W$M=*y{y@P%IIohSk}`;MOY-wOs$7pH8st(TuD9CPEZW%GNPL(QS^ z4k+=N6Mn?r2hzZ-ZWa?dU#67JhwKGR`rDe|d6(_1f@tAzSX<%fs~ej_^t zi4bEwlOj_K3x)gCzs3Qo_t5IJ7UNxlqY}nIwoW%~OgQiRt=E7|d};hG!b%Kio+|a+ z-*c=JtW6#gAG}!|gon!<-?i3bA)pkQyOuzzuO*O8xXTH`c75I9?>?0JvqaDz_zf?V zNH7(F4a3Th3qB&P1xR;*h|;M`q|VOH22jqtoxD2z2H`dJicW;qh%*Plolcos5H7fp zm>#MFLKWbka9lU6b;7ifr$_js*3h0Ip_RNNF~XLvlR{O%mM!J0e(m>-*3*ZpT}Q69 zWKDCl;I{fRi9FALfmyj2@a6q9AaL}?zhfS5`6lOtyxNe|hFcX~|% zA@d2|$%(C;XsuCRs%}wUDx2yN4k|dWdewAM<$1lLg!^^5`Uu@^OSK@1LphCc?)h)` z0Wc^E5D89!#0)ho-SVMN$vzc)(%Vt7l+Xt5BG)6NH0(aJZL1^_J#leJ0vl4dCc2@s zNsyG%qj-%|iL`MQPF)6yalU!kw2IzCP1f2P>Ei#ViE{?vpj*@cq=FJ|=b%Pr;p?p2 z{`+mIgmpTAiu)D1d=Gbj`5+ZKFj&g6n{>6_x6tBuJ$vW4R$)sX171>t^v?@7Ti7!f zyKQ+Q^{MPcIp$Jp(1*I3^73}{^xW(Fd?{H!=-1lAF(DMTwzlsIoTf}grI|PDWnPts z?6UV6jiBmzeQ1wUV>H$OH`PrwN)$BrA$#n5V2*{1eM+K|GDv zciO0aKP$H**(0Y6(y=?J@e=31t=fnJN-`;i+5wR8WMG}^=sY!I3<#oI|91ebEeBAEjUZYUfr>lb~h*zW1FA2 ziIv`wlahAPTafhNFFXhE%AAAvBx;8I^_ZV?};k1g#hHnrlz8H zYn87^3b3a&@(M#ia=W-Au&X_StE4@dr=;@L9ec&L=b{{JLi%d<#goM7whOvz`1be7 z0%_{4jbH(Nwvp+mgP|J$W;)#HY;BB*{06b6=!CAzNcOk(ptoXtMRT2V&9&|UZ!4bQ z-NAP^Buf3Xhb8e=!s&^77H-Y!_Ke0OJBOyWK+n%Qp9lc{ohd>dvL|gONNXj#`$u@n zqAanUO^LD-@1OR-UvtVL62?M9m*!r>&AZdGvXv1Q6N>-x9|9R9Lo@?GVJnDutLOBg zwC%C*L6VX)4N#L4OR-Y@Su$l2Xh2_P6KX{)@-ht3APW{<7+npJ4SP+&`Y+Jx!Go6P z^E>Aa`Y!vkFl`RRi!8{)ez-6CIS#l#wV^k2+O;n^jsr1)-Ze_^7m7itog1%9(BRR|>XDI= zx3A6#;GabA1>ED3KKYu6SwrJE5@o%#yr8^v)l5V}(zVylsAzYdV`sYY-lqkPxjTpp z4Dk;5_iEw8TWTmHmXBL->Q4hnXRs`sxj@XrZ&40+4t$|WgpRI*5vwj?lPvCDw|2Zx zoKFmRSxTt*i0sB|U|H#sD|R+q5+V<}{z_DB>3QtO?$^-L!T`Kbew|3jdR?ZYl+p4& z545W_kV|gkOapF5Tq_o=h=J%^`t5De5v_|~5x&Fi&q~mHR&__GOj5E#-)ka*>AqO)4r=BOr8*Nq?YV8YCovO@t&+c)oqaZzqK< z&>cr3m_)@E)Ne8l5y-x(_Alpa9Ey%*Jf*Z&k5~0ZGLz^QgMfL^Lf>s+aaF47R7_k5 z(6UHB)@H(vm$uL&BufFQ_Bm$=<`qmM+@j?tm>SU8WF|B5Zq|Ald-UR&gh!*H4UdET z%XYBuBLDT6$+mJM%{PF9^a7ED8l zK10@b9Ph~wgfMMI*5V7F%1aX)V;sAyt(nFuwQl>y$6hn{aE&b#vYK3<&l002aDwA27x(qd5%pGZMW>OUSkOVSUv0c z$Vs-`e49S@QrZ*xK&~cA==5m9_BqU?YUdwy5cJK8TpTO*h|YaU$W`v21x4}h=T-t? z%ivey4(viS`Y)i-`}b8^9iHcMYUY1QOluo%j*}7PX4!fnBn@AZ`?q67K{JE?e8!g! zKe(ghua9n=<<7UU}Fx5X>xXLwbK}Tt&)R*r8T@lA;%Ze@dN;tNBd~m+VCaC2T zqe{!dE}x`f&z^tm>KcZ`g(IcrC}`z&-qd?N8mYBIFQkpe#R-`fXz&t;@<9oYtEV>r zTE!gyYESXj>m`JSYb7lR4%st;qWEQ>y$$(c<%A^5n7>Dxs&`mK?EaX)4qDAqF-vO9 zv!=zw#85GN|4{q?<~$9u9czsYO=d5vYBJrI7y1XzwY@%(NxJ*sgvgZ~k9~9cAwk573qXH=ZN2m*U}dgMT4rK4+|<`J^clFY%*uGhsJc`m z4PMdxXY{8J$3aca%R!1bY6r78J(itU+MaYfiv$x=gt4cLGw2P}wm!GiqqlMeso)Y$ z^x{GWrj<6$_C~xE-vfF-iPG8+IiP63+?VtSzi2J7UeIY8R02_cYy9YWxxX?6leHBuuOm7NLpxfGA0n=$~}syY;iFB26^rN>+=WwS;Q%Q>;HMOhuV84z78!+UG1LHA#)lJLC`&h=h0C7sx3ghr zy?7=qd)LCQ#tQWct7suRuHB-~j>z}qU4N5)>L$Dgh@+J3cR!*J!}$ue(W~n^_4IG% z!hPjYPq{Cn;(ve*IN~3EI1kqQ+D)4ck3I3b zex!pVNIGbPq=V(k36uOXM+3uJmrb>8MAEfcC=RX@9aK-__%zDz|7aM59GIIV;E+~; zw>U%CsUF!B5PB@5>erY$**1+fc$)$EA?pEDs)wqdhlZYayZNEAzB|Vr*`BN)4z(3X zpOl$W1Nqz_bRACjfwC%8uFUB{{x^Z~dSNiR54={PEu^Yz%bmMi_kRugN~D+yx^KG= zX{z3SIC7tTNd83;%fu`9pgfY_-EjO+f{32f79dcx|@-!I#8=>doL@JpZIoE zU5|et=!oI4Y2Yh|+#3iPLRt%(btRh-=?v{hLQvARyo@_vK62fTv`DPyY^Nt7$3Iy5JCmb|^Tj>kQt9*) z8;z^(5Mh{sVw5jLpTp9$S6)4VYN9Z5nPFsq!jt9Y@9laq58)j!$jTF-eKyfK;0!^! zx=Aq|Sdo53n#;ZL1r3iLSJ}h1lW%pZB5^&BU3O)rh`XmjS@Vd(uZ{#(GD5POSAz-? z{_Ll$TMh(P_Bf8e-eRM4ZdMlBH7WjnTH}lW z1L4G_A}3Fl*oeta2myO$sl|5bTl?4SF%*8d4I|6W&TkPzTuJc0e{Ox924<>OQu1nT z_}9+|j~-qGhUa^w363T_l)}R}in3y>G__C`P((_s5>QtKe-hKfqr~#c|IX-d9 zv+6o_YD*=0OQ*4Cj^SI3sp3+QVC2l;i{HbglO16oS``b;maVpEd;7Z`iKiO#u4LaU zpJdaTXZ2zIdImaj76p}FC&0_hS?VjUUS-TKyvV!8Cb%=6u7K1q^4DxxPv)YUeS6ta zAcN452ASC|K?z0OdfVC$ZcN}hu9fl_Umjbat-mS;YKT|;` zsLW};(=wgV9O>)O?v{I&Eh76<#Q~|Z`xA*HnW%icM{c7VUsc|whax1v0c)x|Aeasy zm;|p;K25&=UmczI%AVVqPcDF*<8QD#_qQyVtl=+2{LZF7u5LIxJ^c<6UmG=*-QMYo zjZKNR@Y0}?Yq?(oZnHf`T5!o|G+^-w)?I} z9bV{mKsN-njk%c_(iF?St}mzJwh6UTLFB*U#!=m2j6R3_%)oQcJ+ro zY4wCUi_~+PUnOWNEve!0C-LvY&D79TZ>w3KXr>EgG+*F3FKbMW;<4lKF2Ifh=WXzB z`=L1#S*+@JNK9s8=&`Rlk1k)?&WJ-aS4Zw>8WU1~--3--q4oXkT3><|6k5ZkSyIm2e*$4MS3Q3YxphD_3u6<(d=cJEv)ja>m z)X>zolQ>)RIaFAVGQ(9&&216!R$~QIH9^ok_QE;!k!OMG(4H)NBl>@%qjM(i{gPK^vzg*+@5Y4>>cjhr&A0RK0GJP>N*u zWqx8(8eZ_y1m{z2RH0ss9|;|{((j;2#zI=u690mY_fG&2{f(_|xR zb45vi;mLsy4FZmxNYKm4+0NX}{g3@4gni&-++xAC(6UXNA1!hZZb6nI*9m)RjsTK!s5hsLPK6M3 zru%0ge>a|P#iw5Rw4Xm+`<~d!XF*H($`)8NWV5HQOW|w!|6Jc7>)|UEPu4X1S7Swt zwIF#x&%*YL9r3Z@-pD27_Y+Rrwc-9sc%=#>^3`rtSegReg^T#5iDE`v1oeFt4zD^W znhp7uC%fIdeZe00d$SkWWm$c=wf>>CH8eSz@j zrthoob3+^tUbwJ1X@APg5ah&I&v)qP3CIX=JLBzd*ZsX>$HCNgb^Ts4CX1HsSemN! zhdTzbJn=MFr+S}SmLm7w-c)5^p@dgR0}Wvn7d{GBd>U03ydj7;_y%oQQ}sQ0Jgi^D zhpr;gfb66mElW%#@R7Fe-d|czkvE_raT(GzyA0$aO=5g3`xxkHG3(;xn(mEknAn!-Kx; zl~9a;n8{9ImB^j~Era3iM5qnPsgdT4Go)?h0%0|Xt@rE9rd#bCa<5m5>OQx>mov8{$_eDqD zBhAjqDgB(jl7RiaJ&E;!0R}{IQ6yN$4NrCpzrq12V?kQ{2I^xYPQ1q+BY~Gj9@ysY zp*r!t_E;OU0v=RKNyKj)Hl$?#I!GZPm|Hr>v*HiE63{Mo^w4-)d2ga2$5EXd-9xO` z=exT%^S;t+ytGg5HwqYc6ZeQscJQ!lPAn&AwIGn2(|zz9R)E9`M(V9LXU4(BNFtzvU>1B>7aIM<;IPYm{m3{?MxGN2wrjzk20 z>@IlqzMfXo-KI3;=}H{LtBMymjO(M-A-f*XVGQ1Bd<&Oj(SF?YmP(gIv4dpu}7bEXddey{8G@-5=^IaKyu(Meg@TFsk=Y&^?v*KD!T9 zsMh$N&B=(WhmHq^BX%!(ffpO9hNOABBR5TZtAbT*H_zY`RRv(VJ(u@kk2n**()Vqv zBg>}i9~<(Ai!Q{g@ZK!-MG|X?w>gF7{@6+p%;YW-&8Lf91rvqj=XXLXdGE-2OJ_T5 z_9;miigs|6n=+91BXq&l^=&~Sj4BsG8sJh2*7vemXb-&UiSgRCYl7h=;{*qjKpd>g zJYXvs++o<{bFk!du7}<*sGzu2cq`JKI!*|sW;h16OQV*>OWmXD^71zWn{AKc?rgrv z_*+9X)%)jYSy@?LjWkxD_$I+V*y9plCPSh|0qibNSw*^%FUsVz=U*s#CklCQ$o*@C zT3sC(7`m^LkdZ0r@C|HB%tLxi2qlx)c|ZT6q6Oc64fimcklG|u+4{L4yoF2;uImY`(+?kQJ)U64>7>ajl?r) zUTl!6w>wBbG55q`u%_nTfeLaKxXHQKr6~`ae{c2}Ikcd~A#hMuV)KeO93X_SQfBnD5*b~w`= zB$Kl^v9rEK@!+Y`suH(sei-x5MRu!4PJV{QyPT!n8Zi~z+cdCcJ4F@9p}Bgg!3VW! zyEu|t1}~bW<4jc;ESn{9yD|(wwpEWwonxsS5X?c{W5?1*9#| zS=LR@-=`qy`SVH6zsfpLdhYXAkoQ82N1}Ax*1CrIlu9-QYR+%9`|$kqCOun%9&j1S zDZJLU{WWP6Q^^S4dRg7TdOzl}AC}Xjbza$**Z_@5wmI#3etvQg>8H{l(1=JPcqT>Kdl{x+c;=bjUOuR; zef|_ylGLNEh?y#7@h3mDd{1TFrctW*zDObZtwn!%<;CXt_+rWV%Eq9qDHe}=aJv@@dR86CR(=qO-CjQPoEsYox>nETZ&Neq*{2K`8H-w@LN z3PpFe^)j^gchE*gMpZ#a4zQFoqfqm*!t@hUr-wClO`HV!!7&R*jVE$5$7#q z&QEwTS_pR)P!p_F5iDjhE5tPZ9z4hNjj0kUe&^>26Kg|x(?{5|QY4~^$MxCv0xToM zmZtZ&5RMeaQ;Js>@&*$Utu-#%$vT6}cVX3a<3}U8n3EwT0=4jQ=hmUX7O<`%q2OSG z>D&a<5hQENYTgAdne$0Dhs29}d?FBZ^;WH84d34Ns7BgMet1_g?2bKq@aOTZZSMm! z44Z5~_sb$vTJ>n1G-j9K^f};>iKhdbt>7NtWRQr>)vHs11jqVuuahSWmPk>!;- zt-g9Q8ENzq5ER_DyOSWoy}u1er_CF+e{dfloipdtn`k!zBh{N2uD;N`oFMYeQWm=d z?!2z`8~ihEfwvCogIlCS`#>jZYt$qVaDDm@&0F2pT6~-3io7rC0o)vc_a<=r8FS*z z{DCg!mLAs&A*ak;S8!9x}jsBBuKahC0WZ(zVn{Z)ATgz{rmUx{ngj|bkB8P_j#SmaUSP!fod-&!moM6=%XOFIGOruZAQ2Mj01_B!zO=BPdEk6WGCxHO z6}&$E#u~^_n0}+JVKr70LPA2~rBByf7e+W4@1w6NAOzo$S9^v|h|heE-3vUvoSuL^ ziIUORNv2Z?42f7b!h=u|#Oqk^J+U7zj%wZOZYS>Mo#Q;)Tr{aRsI9FG;-)Z3A#P!LoFr9`Jj; z9{xJ|s|lytdylasRx-jU?2UpM9jKD`9pKpZi0ikLn9CgRW-!!oeh8$B8bsnD*MxaG z{eh!g`{3^i*%39a@~;*SC}uvDE6_>bxts1QiE5jNuup`tUlNCiq?7M+`iUUaqE|N& zd*M*Q#}fkw{RqB5O0oWd=Ru3ajdpACsev3z?*Z{wocUSaObm&D~V+ejB*)$vIFR1 zoL7jNS;T_!Ul+R#YHeg<@z7>8sNKuo+0fJkv|i8^Rg2#}A1b828X5N*HH{~YR+U(S z?@?PZas&8y;7D0`w^7vzrC&&UP9Nv&Sak~s{3 zJ0RCT+?w*H_c2JSAU;4VwCNy|ABu)>j^EMHB*V&o%w0?XCl~xLY#TmeWBdl zNFpB)qlp%mgJN}MvO>;D%U7=sDKgiC$gIs`2?+3)VXB@zyWPoXgofMv8O*$2m6pyL z0wMhokXl>wczV`bZ{H5M0^{g+8ZDx(Ed$3za0MH&7#M$pL%H(snE>20b-+Y$Px)Nm zYb_st)=!aNZVYDpm<~ll zy!cJlxyh;59vhI9p?2*XB5~-)xV4ibY^~0E#TbV8hb7~KSKPVq4L7B|&Ib1Y)qy(% zaITf1x|RQaz=c1+%$tLgQw4xe{kx9ue7M{G{lR32kP$EMR_B3&Z~c@WZBd;~4vaus z(VZkU)q|uUOTKNi9rN%Ilqr^mbh!*1;U!sxd1*d;I&JY+`PN;{dK7zL8J)iGf!}Kc zZ}#C`S@#O50d=3atPpok{-Kc70$JCAx53i}D0z&bN1O~+nD68z`pJWrVNV^By@a<5 zgL_>qdgl$TKzgAOOhdD~bI3cZ4Ia978pgdAgNDJ+LFirIWa@E&=;uJe0+PzIWJDtb z$#;@tkKA+{aQ{JN#QDI{KvIoxHN@qdJ#s=Gk0tOtuL6QBA$6Bx*Da*7e`pff%b#x= zMP2c`j0|B1m3UmF?Dj5SAX6T&wH@+os&gG(VCKe26z28nSZ<&FK2dC%J*7fIlk2uX zA>g01>0vc8!hKemulpj+>~|=0#)}0%y`z8hAA&|QLFsHIOm9*1 z$aX=o8Ccmfo8f>AJ}UP$3hSx*NW@4G74}a6F-O;jO*yfT6{4|glY%)_kwALNOhnqO zN|y?uif`;`^R}0#T!9LBvf~S>1@lYrAUsA}Xh_jkTRzlFHC`M1eA=uVLDzdArFkuv zC{Z(_C^LQixlN;Xa~EP_L9Adb1_lByaVB6a38tGcOjl0vI|Hi5p%Q)8{xv>y-Y%ui z4J!U(IbJymZMwU zK&8Z%UMmY*_c9d@VMe~wc2S=aLQL=Etlc&%o!%GJyZO0Q3!r(!>`MW2i{#UolIw&y zb+tYHy*LzrLRaji+D+pwfJ)&zpi^^gnUjl}K{Rb-=K9oWbsirh1_HP+MI0ZcTH%7? zVMwQKME}z!7p;b}9XK@Mk>2E6D(;0w2Dx$v3cU`vU9bc$KE?VO9VzmofL43;{mxU>+Oq2TCq$$J)CSX9HLl0gwKq{<8U6mqv$RcmAPxs4cUEm@ zg_#vH+aXS>K|#fULBY*3fuSa@0vi*zg(9F+?BRrMHy>Iw!qBuL)P#Q9Z_p6WzC|*e z{fg;`y_dm-SArChz*kiJs;ZG^*Q-PCd2-Sk@9xuow;D<-3W*~Q&p?3eCkIFut9m4JW#7*(%$BocxqFiWF#*0I-Gg`Q2%0o7;C0LMG{1%!#DAya z#O;=YJ`r^-Tw1Man;T;(X8)eJizRTQKuk)?){T|DO(y5JBJ@0MS!s~ssRdQi#7NHT z)j%j_2g;6rSW6`F17b5FFdohqXR69TY_-7E{&ft{@*z>rNo`0@IBT!|&MtW1350iM zN&qpE9gMzzc?N8A4cogGZt4x^x(ILd*X?x`2mcxx?#3B>u$M6$+J4S4ags!}9)^P{ zu%~ZC{GVosfIm%6i=O?uIlZS|S|=vN5L8}whwrjk)XVH=MB*?&)=pdQc?Y-vgZUkz zu3D7V&NBm%dP+xG+<^FahY z5LG1~wqgLoCjlnp3g6GkH{UDju~sWi<g}kolldPRpey82kAilNmR&?edH3jlezODl&1_a3^$;qhSo?w@Gp;D{492 z*8TgFzTh%J(d8bsp44Zcb6%t0HyI71>b5x`B_Q8hdwYR*i$_FKR^;zejXf zyKAVPcEb*H6<~}_eycZGXli#d{NqWSnTZbuv$5i}HU<)`&BSDBDZ$tuW*H7BpB+6e z2t)(R-x@(cVDm-bZL964J65(ovDAW#6^c{MVCdaw1Ue{eB&gN`nxzbgqXw8f9Wq_`O5S(0He_9+I0xdAta&vlmHH_7!#p#jeh6+ z_X$ON>wANJ0|Wj#NxBW0A6#GSHNErMcAKwsflf~-Lo(AZbwULl$cAR;O!-V^Rvw-x_$)Ysonjz?`+^V{h0V6S*Mc3Pi*{nA*6cQGzYr%D--xdZoQV_7hof_)+(RqTROR6;C1lT1m;D zt}w|yeMFn{k(JAr)@;!`pgjaKcfOC(fDtqKQr-QAuQ4yFPsF(u-mz8){~ZQ6sgpFS zQkqx7xo`Ar=;A#%_iew+EFPhfUpD=nN)D>JY{W@G5P{9S!}qmEZ-ZB8L8gAO;8sB6)dviQ7?jh?7~g#KSo{;Ko-rdx=A8{W z93n&tgz@0CeMTb+u7JfL2vu$es&!o9)+tXN+i{herfsRBahd!cUaBi}<3e;Y7Lt47 zKSeefni_2&qp}Uu5vrRs`%%Ds;U>x+h{L5R@l!l&tZ$qPUIm?(2DtmNS99S?j8P#- zON*_OGFV{VS?JkSo=ju3&DY6NW za^5idEOdXN^-$E^OGhGOk)<+N4QB#;LjIPPme2ca8~MHr4hA412Z@$4BTtzTy1KSw zweT8U7Z!8KFxa$0Nw*7GgdrPS8Zw z2`nRUqE&t{S+7MFZ$vU;NM!`Qbt)3B>3!>oJp0NQ(HxOKsX>~~;y}jzkKW8B;QlSv zU}`UAuT$~v_NV=}w2}4h(tKHbwyLSi`&&<&{O;P`s7Heo8PqzBwq@5|ee1r=T>*hU z>Big;AdQFuc;a^5kX5;m^Tfo)@>cP_APoiobqd3)K=;~8Et3BwBd0gSi0E`S3=HZZ zXutongS3{wI;!khwJ@Go@&clSe|60fszg4p&_qqnD>$3}teN2K(k>Lc>MpjF6c{sn zzFv!YwB1Cucfeya=R{y&@j88J-j<9)8oWrImOl9M_%Mi1zk|vBn&XyMq$0!-QYIZq zD`rLxWB6)bGdW7wLtQbVFc{);Hs--mW58{jq2~SPjPRqf#pvEx4N*dWTJgRjxV#od z7gS#FXgiX=Kv=z<>hk0zO!xDNPxNGmyb^P+M&?r!S#O@G(h$vf+K!UbfVDg`P`yaubvKya$kop9Z zM!w1-xtm|}CX%R%Z{&gWy999*DsL%k*L!2m_VxPMX^0TfW`}5FN>}h`Ve*M?W;`%;bA;JbXy1&Gdz@$3h z17GVipuNq2hGWjmz;PQCV?4BrC*HmobksWo5dWZOFbwfJZ1&Fi9e%<^52Aua=|q6q zHTc#1Oc|nbmzSTvN_B2>q~{S3&18@J*^R_Soc0^KFmzsiiw;SJEBXUu_*QB*D46$y z(s#Jv0CPMV!GxcLQWGB2KJgz2Jlk@!b2ALv$jo3<$-7?*QQsoEWWhpCAx-kU;$j)d z40l>&1nwQzU$@H+|4-N^V^EG@)HNXfq=qPREN<+iCu~FtwJREBXt(|N{O9!U`^y7Y zfEtt=qFa(@|Jk_yr6+VO|CMndj~6(sJPJ<1RY2TW%x-mP3)1P%Obl_0l`45PLhF2G zf$oEwh~jn+Q0liHerZLT4v;{^4Yf?Xm^l{uZmI8RZ2Cpmv(E+7ABrZ8ZbP;K`d-l7 zAznh-A0HUz$70-2wqYu$$brouSJJh~BQLEeK&-L6Xrun+f%Z!II-Ns{z zk$p8&v{6z`QLn!B-`9(J`He2~{zMi#zg<-)tzJpD9)h+@ivF9kt@j z12aNS7BX)_5C**6%)sf;LlHcU?q^meQzcaXjMs2d_F=z+!U8mrhHnFWdM8V_T&Moe zufXv*%Vv??+6|IBX9Mo9%bx$}@%E$QI~1LE;?=rq{p}k4!6WIqz+z~P7y`7@!1tPN~|+&DIA!4UA!&Q6YgLj z$Aw8Xv?Jl;o%15XTerq;_|VqV+R?GbW5U_PS$W<3)ZO{D$mFz9N7YCK)KBljvPgr6 zxO-r;G`*Qpgb`|$QqIm-!7i9x?qX@Kfj0;GOyIiLLKFHL^RtlyM}AKp@}HW z;G4%y2=~`~@4Ne5z-@Nq`CXrRNsq6Rcip4<+2O3>CjsQUYdt+m8s+iEK+=D$v4V<^ zU5wh=e*YeAQ~ZUq8grY?c3sC6XR{V|d`qIZu^3F`9%m7_Wa`o;r5(2riu!Di%=aGu zF67dLVea`6Zp)Rs%j1!`Q?XeuZBdfz!so#o#`RlDqO@4y_Yxy_CPkOL%9K6V6Gg+v z7b`%sy39*x1fviC(ZSO{B%XfmEuoAWhIG~0aPhtZp531c-3h&Z-?#Jmzx~9`h4NJ!HOL4p(f;(yq#HKfMbsYD+lAMx@m-Y`F=k+jbr0 zCu{^nH#=qFZ5pj?1 zT19TvZQ|Q_H;dU6?1r0L$G9_yp!ri&k4AsS)5u#UV z)l+OPKXaWG7|}B|kY01+x8Xo--LBqH(^Q+&Oc4Pk$fX`)(ii_BZ9T&lMC$iUmJ^?t z&T_5vxJt{%H0WeoT`Wd`MNq7A#H;*6l53%f#k!p&a?>v!L*qe-WYLKK@IU+MSzTz) zhw9_coY@u$7fC!_izcP4w-9Q))aT7gC`l@n(ornKWMN5*f?G!Iklu`-BEj8xPx$!g zsJ(+f1y@9M7>=0G7)_065%>4u%iSP+c*k_vAn}HEs_n4n!H4d}8qmS26EzhLR7C7t ztQk6{Ek-YV(KtddzaSI&<;wx)H=eA#8UHmJVBAunI$`j*3}hsg7!nvx3Z$o}Gl;-w zOqEgI!sVlg7;08*=s5#$ErQm)Pxq=4=D+T#PmAj_cvh(9oLwe2FkEewX{c{#xZCZz z`frUyxNj4Oi&4e+iC<>83pFn!ZS>XMuTGOn-BAQ>GOaN)wukjAnc%wBS|Ew+>N8q95mQ4I1XL`RlIG zz4hYvgG9K2kp@KWUh6=JuvItP#$gbkW_gsdci{*2zz^iDxR#B1@FR9%T2@@Gj9MR>LQ4 zv?*-&FL?vT7|t2%uY`Owa^K2ZeS9WJgo?+N!+@={>lkpz zd&r%G<#4B!M7M~DXhaDdsxlZ%)yztNMjE>n1l_G9CbL@yUcvKwjpt_VOWv@>2YTbNui)zp` zm&wq7^41fl{JpVzT7Ij!p(brXmHQqvaY2JtIPFnzj)5o4NavpknZ3qqUOIqZ2M(Y@ z^Q`J^s>Yq~{3XmP6_e}PceS_soo=zpl#8jok_vZm{)++q_ydlW3hqtmM&$f;HnK{s z+k{*}HQd8JKN-ZjZ^3E!fu@Yklk_=E^+DL2wX*p&ZB&ht68IXr;?0tS6YFI3Zyd%D zuM_wsqsIH7;DXi2?)Emg?Gl7a-NdFmHjECE*6j{*>!G@7qp7Kg!>G&d&Cu(wk$8hEg4-$qLCLMxUGM1&IP;v$l7T9$eDx$Yj!4@`dU= zI9^|lmjQ8MeDA+z(9F8+xYRzEp&&YFfKGPG-hbiJU8`BvX5qwc;vE|#g!IQtBw!%4 z8_LJAzaIWn8XO$lcgli)A)68=FuLo&jHAdV99|8vbxg-8T2}qDv-o>OI?b~VwnE_* z!=j~ZY_p%3y(xtads5i={Mo8^v~uq~^T%tEgspAudy-|{U>G)fvAGh9M%BaGtzAQ$ zloY|O2dRl|I&?VN;{rE2ud$@FwlK6qWCHC zKgKCRCU`i}M<1o>wqXsu z*(5iQVM=57Rk#0&7lSK~E<;_tdbJx8Kh{@bX>X8n{xW2KqG=DzNKSwWtTEW`%q0ap z6Ic#k?b%aGDC+=jm4tPND(Z?mJXy~pKl3c_$+3vZND2o3lKKv?ss0&oQoiFod>I8Y z3N)l)N*s10ct;HD{w-8-0&q~pB?crA#O3Q7(dUJF`K`6M%XAA@y#IQT?AaG;o!lL_ z_RS+RlWu*=rh*qXERfH20LavdwW{0##+HXmfA-cy97pH-YU+{|D`3Lh9p6!R3 zl6EA__fM9-Q5K(=R1375#gl56!ACT|E}C>kXi()m=+}`_H|4e*E|*Ps%f5eG8WT1eDq%8zZ;?g+b-up zV+(Okp0sSS^+=d|z
  • >2ML$!B8$JbwzQ2(u{hW#8(ki{I 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℘QB-% zyS)7Ms;?HK2>e{qmR#7C8|)gB5b=>1vZwXh=*!nT-zir4X9P+#uvj3Cmse`yxqwXl zH9^xbN5Wd_on{QfE^T<&ewX{)sizKv>IXf-%};+z@^0x~mT9;ZaGP@WDbhU=KUYG& zIpB7A5yjw96wTdbgmT1q+CHYMdlXrs8jtSF^=O1H6UL`L%}13YiIr@(;xpj=1oiYz zQ=zGVQ+^)p?(D)KVjJk3k~GQyJbwBsJ*&Q+V>|JuZ-sS+*UFVyKFS|N0N0}^I+_P9 zbj7Mqe!(9y?V9Q`Ef#GB{(LD71SlbL6=3=S_NM&8nrVkq2^9&KC-Ur!bL&r{!;M0GGNb&FZHs zjQ#>osx*-uVaAHxfY;*L)~^4p-+BM!@fNHk!0m;A z;&J*409Gpg&{*%nqeA8YiHZAt^!ya3JjmV)i|~!4v<(7CnWy!WRYxzJ6>E_Li3a#e z^=SxwZrH=*r@y1LJue`O0R~qH=(pd6Vr)#{8Nu|+AmGln8z!$yV%ivXwYT~yg}GB4 zevgHwaAWS^L2jA6(@I2=*jm&R(& zovn#V8$Z+lwcO;07hqy<`o|KrUi>ahMfOg}mcXFWtul5X)oz9-4K#GTMasepGcz3< z?X;ph&(3zK($4=jDEG?=B?D}e;Zx@owh;@$`SFRu{rD~EIqBSk{l>n>{s%aK6^WjY zE-GDKMyQ4Jo!0GOSz*dT=T znH}PB>bPA$R}s(fT0(tc%4;|0;ZPXa^QM+DT$kK)X8O&hE-DRYp?zCY>4-lTXp*c@f-M*;oN?3G8q zdOd13zU7N6=DO<%gB&UwR$4Cf+bJJby9n^etp^Ka;XW~xlzOQlOqv7)&c2Z9%p~%9 zYR48G)*ySJHj<;TCJDk6O9j&lN1Dc#3Vmad$^-aYeR}>1JkShKIq=|5P94fiBS;0? zKX>ne8wS{rN91Aj*UF5IyqST1+NS@ZKq*69v9WOiBi7D=&=!Y3GL2{Gn4A2hmij^- z&wv!UC;o>bmj<%GM7uMw3Z5mk)bPdRn%`c0SV!C4WmCY6iAGwNjXPC}cc)Kw6l@&s8vBq`Ave3W*0Yze z@%IJ%{2Qz@L1A#&C;%@dQB*!!=~?bm#pU>q1ADd#jLq~%jC=?uc21!&oAPOFz-f=L z@TXp+rx5)P1tKtOU@&{$a6~v((G&L>MZfo(M$Y{A87+D(H(s{kp?qQvDY&_-)0tH; zPMgec$0I%Q%3y6dq?z`kHx!p?wteOcG(VFB{tK;Kfef>nf_ShHINjvR@oH_Ve=vG?L&MD5Yug!>E59qLL1zLHqP#==WBz@ zF@MXj5p)J-P>`Et1F#z70{Z;{+|qKHUyWLzzQ1V#@ETd$k-{>N_bTBBS1OHx_oE;Npp9LECcuN;1WYv9&YVJJm8gM&!Z1>b$EPHvS{pKt^+rl z_~phQeGi@n-X+e{f)?(QWZu%llAKvH`+0LuEs>`2?vE^xpEg65_Jt+l-h##1K7Gig z%KE}Qmg$r8dKvx1ix`qB)qnS5;gb_ifXVV|(GZ|K+)3E3TI%{SM)q8POa|tvvo7i? z?M!!3zam4$qWoyGTxJ~vmtK8GDX0@92pKA+hOOdrR#x(9T?#NzldiEx`jKG@Tg$-s z-w~nJ@FX*R2cXG{?Ik@a%;c3*;vI4>xX))DQ-wd;t%_imWWr6FygSPXU#Kgg25P5D z{&KgzeA)k;of#uG$&ts`|K64^h|4Qd znP=h(WL4aOJK=IG-6VOZ(cf91KR**3zfpw1ce33K$WzNv0>BsGUJX%)=3rw;FyklZ z9_DnIZoX}={72xPfC9T=^|XR%|528MXJ{JJI-y&b1%4_Tpbe{&D-jw_u;CO*dIewt`{Dxr&E5ZqCr8`Zm0u6$PckixG+NeS6 zmA)IqvwBt~Y1$era+Khw;k`7F;Qr2LK*bXmhf09-rom{VaeK`ZbX@>VTkBhdz4VgKg5P`1u*HyS_xFwP&2z)mYd(>*T`qBcJ2D2p*Wk2xOzFZ_?!NwPInSt+v zqd}4+2|TNA7mZEZ&?&{oi}9UFZ$gSlFgHk#>?#dY*hiM+sCLe})H^-fR9;6)b$?gspp(V5VP;Q^e*HgL z3qwUeW8qIv2NtZu4!C-n4u23gtjCWztcfMr5dc}eH#A?`h(pkstpn*WCUPn4CWRq! zGMj^OkR*f#j%L{+mL{NY&E%q1DhA+`3Dk zHB=X$@Q7Uvs*hj?MM&ct;#XuJVVVn{ zqP)^u+Wjhq{!S5M$dLyZw{=|+qyxASlsv>(=cElCb2*cf?e`*4{Gn++z0c+>h8G(X zAbYPaHgI#Oz@- zw?fIQl)BFCrPJ3E(x8_7?3^8A;P^lE*paRXEX8#a8PnUr7&gw5T#CIke-hQGVx?CR zA^c`#cWLlB#A8ZEb`mJY;dgsI}BsQa6SvQIK*oWG?_>f#z2(v0Qt72OEY zZ~o(xssT4>TsP8=Tp3m$esQc~Rh1Z~O%u8-c|9j3WyIz_$6fLuud{yfRK!PjSwMmp z@WD(1j4w`5%wIr%rb#_yCXHUTB;4w#;1h$#MeHz^e_+SrlVN18qGSM`c3N^|4Lr?U zP^^z7xhBxC`}3W7=Y93}gFl%kwGSXURu|-0K8g%K2*HcJBR~kV72iLZr-E@oCzdY? zIb8`MG4>H-X_7!lAlAB**RdbopCv{$vW38gkUe$X=C16NRSD-1OmPQW*a@0OE^erK zDtZMQ1`z&u!T)l|_CRiw$Ky|rIIlf~GY|0tgH2^a`y3qFz6k21?pbftMh9F>c`p+a zlK{#?&E#uZ1DzMg^sCO0F^HWdoQcEFjk|tr=qQ;Ny6f^t$-W#QbUGr((RVN zf4hahIjCM@J5ZnGdj;|>ZG5Bvu=uOL9bLO^0K~WQ?Ef?qx7dQ%2{CG=(_=FM0TIgg zl#6$vpar7dq$ylVp2uMh1xyItuOLR39o zQ~2rd-^+Kb9YSs2@8Slt*o3#V*LG9)OLAwGV|VR7JaA$XDshE?KBl^Oqd;DUgy*pOzO@AYZ(LPR9C9lzsgYW(*p&{iHHF_bm$>t8Nt=WV!ClgQ7N68W1G_Y3 zOtmo6P9g0<{5IhYgu_^qjU!MzrIjO$yX$U0+m|qU9 z0`y@d5S=qLLs%&CJm@G5e^=u%?wESOXl-&P*ESDDpK5b?8a?l1n|=AY{$IVx0~F7! zpHrPt&K=~3_!uW=S&~gXqR*H!y-qZ31xwHZ^@?`sSKITNDNag~+50Zo`^J0H`=Gy2 zGE2QrhPvN>V!h0+`NRiYvc>tVbmYBCpbmiMWw7wEZlYljVrVBP+G}f!7e-GRas;|g zCPXlO2P8!km03Ebry0>2imWh>N36LOGxWXx?9rh+q2=?lG9HZkiWE+Zlnx_WwEJZO5!QKHJoB3~JvsK6=)lMw>_hznCBL};aV6x7wbNj%^Ez`Y;z zD)hfXi6`sPd)<}y+3%VrWQPHF8xoG-1jA#zIIJ}xwt>A|H0wLodc{j_5dh)2i@K&C zmcP`?)DP8lVE+pZ4%Zdu$%D34n&gM|DPe~{^hOPr26x_FH}k4>=u(niTE~?FD6iVv z+nG*me0rZMK=cT0&GgXSK(E2GaHWP_(-G(O->y%PeVbp*5*~{DPx#e@3XY~6VzKyP zv)$-9p~%_l!XYE64d45VzxP+{sWG2?vbKMRvfCk;zK8CxQPBhid6b2xk^HU-ACS&p z&KiTL86lU(VRsalVr7j4T2j;>2g*Jvx=8_`3%6{U^yfndWVOXdX#Ub7HbeT3K7zi8 zcKu~^8;DU{cKghODrV={`QaR?jC@Bcx`B>CZR%o)x4#utXY zrp;EFm3J?Z#Df-ni=b%SDZ9B~ys;c5jTH((6E}(qz^W7-K>fKn_~QqE(mnsPcfT0J zzdN)UTK?M*z-Yaj$kta8cJQ|jF7-5=N znLYh8@$Scaz`g)=Q}p_>KZ6)Q+`vJEcbXW?_!sc}$ELl6qD|@l!%d%^cNz#=xonxI zY?wz=b631q?D;zTltN(@cv_A7@|t=S1Vj@0RG`JRL7oi2QG6JdQ#o&&jX+ zV_Nm^%I#Pg@JH@GT2N`C6br~+c4@2s-8a%7mbUtbiIR@Sl2!kD>X#hIzmAvqhb0HH z0U*~x5RsWAW5NiK2r{sZGI zA$v>6-hWKumn>_^fh;+YUvZ58Sj&N?r#4cSv6CK&l-6;{O5Z ChU5?c literal 0 HcmV?d00001 diff --git a/AI/vllm-cpu/meta.yml b/AI/vllm-cpu/meta.yml index a37dd739..d5fb3998 100644 --- a/AI/vllm-cpu/meta.yml +++ b/AI/vllm-cpu/meta.yml @@ -29,3 +29,9 @@ 0.9.1-oe2403lts: path: 0.9.1/24.03-lts/Dockerfile + +0.10.1-oe2203sp4: + path: 0.10.1/22.03-lts-sp4/Dockerfile + +0.10.1-oe2403lts: + path: 0.10.1/24.03-lts/Dockerfile \ No newline at end of file -- Gitee From 099ec169fbae3e4e144ace4d6897da3b0f0839be Mon Sep 17 00:00:00 2001 From: zhihang Date: Thu, 11 Sep 2025 18:11:33 +0800 Subject: [PATCH 2/3] fix a bug Signed-off-by: zhihang --- AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile | 4 ++++ AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile b/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile index cb289ea4..d53f9248 100644 --- a/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile +++ b/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile @@ -20,6 +20,10 @@ WORKDIR /workspace/vllm RUN pip install "cmake>=3.26" wheel packaging ninja "setuptools-scm>=8" numpy +RUN sed -i 's/torch==2.6.0+cpu/torch==2.7.0/g' requirements/cpu.txt && \ + sed -i 's/torch==2.6.0+cpu/torch==2.7.0/g' requirements/cpu-build.txt && \ + sed -i 's/intel_extension_for_pytorch==2.6.0/intel_extension_for_pytorch==2.7.0/g' requirements/cpu.txt + RUN VLLM_TARGET_DEVICE="cpu" pip install -e . --extra-index-url https://download.pytorch.org/whl/cpu ENTRYPOINT ["python", "-m", "vllm.entrypoints.openai.api_server"] diff --git a/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile b/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile index e4337c40..09ec370a 100644 --- a/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile +++ b/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile @@ -17,6 +17,10 @@ WORKDIR /workspace/vllm RUN pip install "cmake>=3.26" wheel packaging ninja "setuptools-scm>=8" numpy +RUN sed -i 's/torch==2.6.0+cpu/torch==2.7.0/g' requirements/cpu.txt && \ + sed -i 's/torch==2.6.0+cpu/torch==2.7.0/g' requirements/cpu-build.txt && \ + sed -i 's/intel_extension_for_pytorch==2.6.0/intel_extension_for_pytorch==2.7.0/g' requirements/cpu.txt + RUN VLLM_TARGET_DEVICE="cpu" pip install -e . --extra-index-url https://download.pytorch.org/whl/cpu ENTRYPOINT ["python", "-m", "vllm.entrypoints.openai.api_server"] -- Gitee From 5ec5ae65f771c1eea45524c6c38eb18b6917d624 Mon Sep 17 00:00:00 2001 From: zhihang Date: Fri, 12 Sep 2025 10:43:22 +0800 Subject: [PATCH 3/3] update Dockerfile Signed-off-by: zhihang --- AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile | 43 ++++++++++++++++----- AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile | 41 ++++++++++++++++---- 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile b/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile index d53f9248..b40c0d93 100644 --- a/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile +++ b/AI/vllm-cpu/0.10.1/22.03-lts-sp4/Dockerfile @@ -1,13 +1,30 @@ ARG BASE=openeuler/openeuler:22.03-lts-sp4 ARG VERSION=v0.10.1 -FROM ${BASE} +FROM ${BASE} AS base ARG VERSION RUN yum update -y && \ - yum install -y make gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ python python-pip python3-devel git vim wget net-tools numactl-devel && \ - rm -rf /var/cache/yum + yum install -y \ + ccache \ + git \ + curl \ + wget \ + ca-certificates \ + gcc-toolset-12-gcc \ + gcc-toolset-12-gcc-c++ \ + python \ + python-pip \ + python3-devel \ + git \ + ffmpeg \ + libSM \ + libXext \ + jq \ + lsof \ + numactl-devel && \ + yum clean all ENV PATH=/opt/openEuler/gcc-toolset-12/root/usr/bin/:$PATH ENV LD_LIBRARY_PATH=/opt/openEuler/gcc-toolset-12/root/usr/lib64/:$LD_LIBRARY_PATH @@ -18,12 +35,20 @@ RUN git clone -b ${VERSION} https://github.com/vllm-project/vllm.git WORKDIR /workspace/vllm -RUN pip install "cmake>=3.26" wheel packaging ninja "setuptools-scm>=8" numpy +RUN pip install -r requirements/cpu.txt -RUN sed -i 's/torch==2.6.0+cpu/torch==2.7.0/g' requirements/cpu.txt && \ - sed -i 's/torch==2.6.0+cpu/torch==2.7.0/g' requirements/cpu-build.txt && \ - sed -i 's/intel_extension_for_pytorch==2.6.0/intel_extension_for_pytorch==2.7.0/g' requirements/cpu.txt +FROM base AS build -RUN VLLM_TARGET_DEVICE="cpu" pip install -e . --extra-index-url https://download.pytorch.org/whl/cpu +RUN pip install -r requirements/cpu-build.txt -ENTRYPOINT ["python", "-m", "vllm.entrypoints.openai.api_server"] +RUN VLLM_TARGET_DEVICE=cpu python3 setup.py bdist_wheel + +FROM base AS release + +COPY --from=build /workspace/vllm/dist /workspace/vllm/dist + +RUN pip install dist/*.whl + +WORKDIR /workspace + +ENTRYPOINT ["python", "-m", "vllm.entrypoints.openai.api_server"] \ No newline at end of file diff --git a/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile b/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile index 09ec370a..d81feb54 100644 --- a/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile +++ b/AI/vllm-cpu/0.10.1/24.03-lts/Dockerfile @@ -1,13 +1,30 @@ ARG BASE=openeuler/openeuler:24.03-lts ARG VERSION=v0.10.1 -FROM ${BASE} +FROM ${BASE} AS base ARG VERSION RUN yum update -y && \ - yum install -y make gcc gcc-c++ python python-pip python3-devel git vim wget net-tools numactl-devel && \ - rm -rf /var/cache/yum + yum install -y \ + ccache \ + git \ + curl \ + wget \ + ca-certificates \ + gcc \ + gcc-c++ \ + python \ + python-pip \ + python3-devel \ + git \ + ffmpeg \ + libSM \ + libXext \ + jq \ + lsof \ + numactl-devel && \ + yum clean all WORKDIR /workspace @@ -15,12 +32,20 @@ RUN git clone -b ${VERSION} https://github.com/vllm-project/vllm.git WORKDIR /workspace/vllm -RUN pip install "cmake>=3.26" wheel packaging ninja "setuptools-scm>=8" numpy +RUN pip install -r requirements/cpu.txt -RUN sed -i 's/torch==2.6.0+cpu/torch==2.7.0/g' requirements/cpu.txt && \ - sed -i 's/torch==2.6.0+cpu/torch==2.7.0/g' requirements/cpu-build.txt && \ - sed -i 's/intel_extension_for_pytorch==2.6.0/intel_extension_for_pytorch==2.7.0/g' requirements/cpu.txt +FROM base AS build -RUN VLLM_TARGET_DEVICE="cpu" pip install -e . --extra-index-url https://download.pytorch.org/whl/cpu +RUN pip install -r requirements/cpu-build.txt + +RUN VLLM_TARGET_DEVICE=cpu python3 setup.py bdist_wheel + +FROM base AS release + +COPY --from=build /workspace/vllm/dist /workspace/vllm/dist + +RUN pip install dist/*.whl + +WORKDIR /workspace ENTRYPOINT ["python", "-m", "vllm.entrypoints.openai.api_server"] -- Gitee