问题描述 项目需要用到 RAG,我们选择用 LlamaIndexTS,但是外网功能开发完,在内网准备发布的时候,发现 npm install 报错。
1 2 3 return binding.readFileUtf8(path,stringToFlags(options.flag)); Error: UNKNOWN: unknown error, open 'xxx/node_modules/rc/compile.js
原因分析 从报错来看,是这个文件读不到,去对应位置查看,确实没这个文件。 这个文件是位于 node_modules 下的,那应该就是内网环境部分包资源无法下载导致的。
解决方案 从外网的项目的 package-lock.json,找到使用的 rc 版本是 1.2.8。 先手动安装 rc 这个包:
安装失败,然后等待 10 分钟,等内网拉取缓存,再次 install,成功。
然后继续进行项目的 npm install,发现报错变成了下载这个资源失败:
1 https://github.com/lovell/sharp-libvips/releases/download/v8.12.2/libvips-8.12.2-linux-x64.tar.br
查询了下外网的项目的 package-lock.json,发现这是 transformer.js 依赖的 sharp 这个包用到的,然后拉取 transformer.js 的源码看了下,这是一个用于图像处理的库(transformers.js/src/utils/image.js):
1 2 3 4 5 import sharp from 'sharp' ;const img = sharp (await blob.arrayBuffer ());
一开始以为仍然是无缓存的缘故,单独安装这个包:
1 npm install sharp@0.33.5
过了 10 分钟,还是不行。然后我去 github 看了下 libvips,发现这不是 JS 写的,那么实际 npm 安装 sharp 的时候,应该是直接拉取了当前系统对应平台的编译文件。这个地址内网是无法访问的,因此得另想他法。
既然内网无法安装这个依赖的文件,那就采用外网安装 sharp,然后拷贝到内网,再离线安装 npm 包的方案。
首先外网安装 sharp(注意平台必须和内网保持一致,内网容器是 CentOS 的,也就是 Unix,恰好我外网有 Mac 笔记本,刚好同为 Unix 平台;如果外网是 Windows 的,则需要自己开个 Unix 的 docker 容器再安装):
1 2 npm install sharp@0.33.5 --global-style --offline npm install sharp@0.32.6 --global-style --offline
将下载的文件打个包,传到内网,然后内网开启 CentOS 的 docker 容器,同步该包到容器内部后,进入包文件夹,全局安装 sharp 包:
接着我再npm install安装项目依赖,就 OK 了。
然后再将这个容器 commit 为镜像(rag 为启动容器时给容器的命名):
1 docker commit -m '安装sharp包' rag node:rag
离线安装 npm 包 1 2 3 4 5 6 # 先在有网络的环境下载包 npm pack @huggingface/transformers@3.0.2# 这会生成一个 huggingface-transformers-3.0.2.tgz 文件 # 然后在离线环境中使用 npm install huggingface-transformers-3.0.2.tgz
1 npm install @huggingface/transformers@3.0.2 --install-strategy=shallow
1 2 # config global-style This option has been deprecated in favor of `--install-strategy=shallow` npm install @huggingface/transformers@3.0.2 --global-style
别加--offline,这是限制离线安装的,不会去下载包,而是直接用本地的包。
如何把所依赖的其他包也打包进去? 1 2 npm pack @huggingface/transformers@3.0.2 打的包只会包含其本身的代码,所依赖的其他包并不会打包进去。如何把所依赖的其他包也打包进去,方便离线安装?
(不行)使用 npm-pack 工具
这个不行,不会打包其依赖的包。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 全局安装工具 npm install -g npm-pack# 创建 package.json npm init -y# 安装包 npm install @huggingface/transformers@3.0.2# 打包所有依赖 npm-pack# 离线安装 npm install ./huggingface-transformers-3.0.2.tgz
(可行)使用 npm-pack-all 工具 https://github.com/kleingtm/npm-pack-all
参考[这个文章]https://www.leanpro.cn/docs/leanrunner/zh-cn/shared/npm_offline()。
注意:必须全局安装 你需要的包,否则其依赖的其他包文件不会位于当前目录下,会导致最终打的包缺少这些依赖包。
外网安装&修改&打包 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 全局安装工具 npm install -g npm-pack-all# 安装包(注意:必须全局安装你需要的包,否则其依赖的其他包文件不会位于当前目录下,会导致最终打的包缺少这些依赖包) npm install -g llamaindex@0.8.26# 查询包的安装位置 npm ls -g llamaindex@0.8.26# 进入安装目录 cd /Users/leozhou/.nvm/versions/node/v18.16.0/lib/node_modules/llamaindex# 删除package/package.json中dependencies和bundledDependencies下的无用且会导致下载公网包的依赖:chromadb、chromadb-default-embed # 删除无用的包(不删除的话,会执行该包下面的script/install脚本,去公网地址下载文件) rm -rf node_modules/onnxruntime-node# 打包 npm-pack-all
注意:如果是先 npm-pack-all 打包,再解压后修改,然后再手动打包的话,必须进入解压后的 package 的平级目录,然后再打包,否则会因为路径问题导致后面安装失败。
1 tar -cvzf llamaindex-0.8.26.tgz package
内网安装 1 npm install llamaindex-0.8.26.tgz
报错 下载 onnxruntime 失败:
1 2 sh -c node ./script/install# 下载onnxruntime失败:https://github.com/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-gpu-1.20.1.tgz
看了下,这个是 GPU 加速的,我们的 docker 环境根本用不着:https://github.com/microsoft/onnxruntime
查看 script/install.js 脚本,发现可以设置环境变量来跳过:
1 export ONNXRUNTIME_NODE_INSTALL_CUDA=skip && node script/install.js
下载 chromadb-default-embed 下的 sharp 失败:
chromadb-default-embed 是 llamaindex 的 package.json 中的依赖,是向量数据库的操作库:
1 2 3 4 5 6 { "dependencies" : { "chromadb-default-embed" : "^2.13.2" , "chromadb" : "1.9.2" } }
实际上是这个脚本报的错:
1 # LlamaIndexTS/examples/node_modules/chromadb-default-embed/node_modules/sharp/install/libvips.js
这个可以从本地缓存文件读取:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const tarPathCache = path.join (libvips.cachePath (), tarFilename);if (fs.existsSync (tarPathCache)) { libvips.log (`Using cached ${tarPathCache} ` ); extractTarball (tarPathCache, platformAndArch); }const cachePath = function ( ) { const npmCachePath = env.npm_config_cache || (env.APPDATA ? path.join (env.APPDATA , 'npm-cache' ) : path.join (os.homedir (), '.npm' )); mkdirSync (npmCachePath); const libvipsCachePath = path.join (npmCachePath, '_libvips' ); mkdirSync (libvipsCachePath); return libvipsCachePath; };
下载的文件路径是类似这样的:https://github.com/lovell/sharp-libvips/releases/download/v8.14.5/libvips-8.14.5-linux-x64.tar.br
然后试试设置这个参数:
1 export npm_config_cache="/path/to/the/sharp/cache/dir" && npm install
最终的命令:
1 export ONNXRUNTIME_NODE_INSTALL_CUDA=skip && export npm_config_cache="/path/to/the/sharp/cache/dir" && npm install
Takeaways
读报错信息
读源码
明确每个库的作用,确定我们是否需要
从原理上弄清楚