ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Python虚拟环境隔离安装sentence-transformers:conda与uv实战指南

Python虚拟环境隔离安装sentence-transformers:conda与uv实战指南 1. 为什么非要用虚拟环境装sentence-transformers先说说我这边的实际情况。之前我在一台开发机上直接往系统Python里塞过torch、transformers、numpy、scikit-learn这一堆东西当时图省事觉得pip install一下跑起来就完事。后来某个项目的requirements里锁了numpy 1.23而另一个项目里的sentence-transformers依赖的torch又要求numpy必须高于某个版本两边一冲突import的时候直接段错误回头排查了一下午才意识到是全局环境里同一个包的二进制版本互相踩踏。这就是虚拟环境要解决的根问题不同项目对同一依赖的版本要求可能完全不同只有把每个项目的依赖链隔离到独立空间里才能从源头上避免互相污染。sentence-transformers这个库尤其需要隔离装原因主要有几个它依赖torchtorch本身的体积大、二进制文件多和系统里其他深度学习库很容易冲突。它连带着会装transformers、tokenizers、sentencepiece、huggingface-hub等一整个生态版本联动很敏感。它支持GPU加速安装时还要区分CPU版本和CUDA版本的torch如果混在全局环境里稍后改一个包就可能把整个环境弄坏。而且更现实的问题是日常开发里你不可能只在一个项目里用这个库一套环境跑所有项目听起来方便实际上等埋的雷多了根本拆不清。所以单独给这个库建一个干净的环境是长期最低成本的做法。这篇文章就以实际的操作过程来写覆盖主流的macOS和Linux系统用几种不同的虚拟环境工具分别演示如何干净地把sentence-transformers装好以及装完后必须做的那几步验证和常见坑。不管你是刚接触Python还是已经写了几年都可以从中选一种方案直接落地。2. 三种建虚拟环境的方式选哪个更适合你在动手之前先把工具选型这件事聊透。现在建Python虚拟环境的常用工具大概就这几个系统自带的标准库venvAnaconda系列的conda还有最近风很大的uv。各有各的适用场景对中文社区的用户来说选错工具虽然不至于装不了库但后面维护环境、切换环境、迁移环境时会费掉很多不必要的精力。2.1 venv最轻、最不容易出错的基础方案venv是Python 3.3之后就自带的标准模块优点是零额外安装、跨平台行为一致、没有历史包袱。你只要执行python3 -m venv 环境名当前目录下就会生成一个独立的文件夹里面有一套独立的Python解释器和pip装什么包都只进这个文件夹。venv的问题在于它默认不带ipykernel如果你要在Jupyter Notebook里用这个环境装完库之后还要extra装一个IPython kernel。另外venv创建的时候默认不继承系统环境变量有些用户首次用会以为环境坏了其实只要激活一下就好。这种方案的适用人群是机器上本来就有Python 3.8以上只是想尽快把库用起来不希望再安装任何额外的环境管理器。我在很多临时任务里都用venv胜在可控、删除也干脆——不需要了直接把文件夹删掉就行。2.2 conda适合需要管理Python版本和科学计算生态的场景conda来自Anaconda或Miniconda它的特点和venv最大的不同在于它不仅仅是Python虚拟环境的工具它还自带一个完整的软件包管理器。conda能帮你创建任意Python版本的环境比如某个老项目需要Python 3.7另一个新项目需要Python 3.11这在conda里就是一行命令的事。如果你在Windows上使用sentence-transformers我个人会优先推荐conda。Windows上编译很多Python包是很痛苦的而conda的官方源里预编译好的二进制包很多装上就能跑少很多麻烦。同时它也能管理CUDA依赖相关的包比如cudatoolkit不用自己手工匹配driver和toolkit版本。缺点是Anaconda体积确实不小装完默认环境可能占用几个GB。其实装Miniconda就够了它只有基础的conda后面需要哪个环境再往里面加包逻辑更清爽。2.3 uv速度极快的新生代工具适合愿意尝鲜的老手uv是近几年社区里非常火的一个Python包管理工具用Rust写的安装包速度比pip快很多创建虚拟环境也快到一个让人觉得离谱的程度。它是完全独立的一套实现专门适配了这个时代对速度和可复现性的要求。uv创建虚拟环境的行为和venv基本一致也是建一个独立的文件夹但它默认会做几件事自动选择当前项目需要的Python版本不需要的时候静态链接一个解释器安装依赖的时候用全局缓存不同虚拟环境之间的公共依赖不会重复下载还能自动读取pyproject.toml装依赖只用一个uv sync命令就搞定。要说它值不值得用我的看法是如果你已经有venv和conda用得很顺没必要强行换但如果你经常创建临时环境做实验或者对pip安装慢深恶痛绝那uv能带来的效率提升是肉眼可见的。现在很多新项目模板默认就用uv学一下完全不过时。2.4 我的选择建议简单归纳一下场景推荐工具理由临时实验、轻量使用venv零安装删除干净Windows、科学计算、需要多Python版本conda/Minconda包管理完善少编译坑追求速度、日常开发高频创建环境uv快、可控、可复现本文的实操演示会以conda和uv为主因为这两条路径覆盖了最典型的两种需求一个是从零管理Python版本一个是追求干净快速。venv如果你只需要一条命令体验一下其实和uv操作上几乎是等价的后文也能看到共同点。3. 实操用conda创建一个干净环境并安装sentence-transformers下面进入正题这部分我会把命令和每一步的逻辑讲清楚避免你照着敲了命令但不知道为什么这么敲后面遇到问题又不知道从哪里排查。3.1 基础准备检查conda和Python版本如果你还没装conda建议直接去下载Miniconda安装过程一路默认设置就好。装完以后先在终端里确认一下conda --version如果提示找不到命令大概率是安装的时候没有把conda加入PATH。安装脚本执行完一般会提示是否运行conda init选yes即可。已安装但不想重装的话可以手动执行conda init bash然后重开终端。创建环境之前还要确定你想用的Python版本。sentence-transformers截至我写这篇文章时要求Python 3.8以上推荐3.9到3.11区间太新的3.12可能遇到个别依赖的兼容问题。所以我这边用的是3.10一个非常稳妥的版本。3.2 创建并激活环境执行下面这条命令名称随便取这里用st-env当示例conda create -n st-env python3.10这个过程conda会检索并下载Python 3.10的相关包等待时你可以做点别的事。创建完成后激活它conda activate st-env激活后你的终端提示符最前面会多出(st-env)字样这就表示你现在已经在虚拟环境里了。这一步非常重要后面所有pip安装命令都要确保在这个状态下执行。你能观察到的一个细节是这个环境里初始的包非常少大概只有python本身、pip和几个基础库。这正是我们想要的干净状态后续的依赖完全由sentence-transformers自己拉进来。3.3 安装sentence-transformers本体直接使用pip安装最新稳定版即可pip install sentence-transformers如果网络状况偏好可以使用国内镜像来加速安装pip install sentence-transformers -i https://pypi.tuna.tsinghua.edu.cn/simple这一步会拉取一个相当长的依赖列表核心的几个包括torchsentence-transformers的底层深度学习框架transformersHuggingFace的模型库tokenizers分词器huggingface-hub下载和管理模型scikit-learn部分评估功能需要scipy、Pillow等处理数据与图像安装过程中可能会看到pip在编译某个包的提示如果用了conda环境一般不会出什么问题耐心等它跑完就行。装完后确认一下版本pip show sentence-transformers python -c import sentence_transformers; print(sentence_transformers.__version__)如果正常输出版本号说明基础安装已经成功。3.4 针对GPU的额外步骤如果你的机器有NVIDIA显卡而且想用GPU加速编码句子和模型推理那安装torch的时候要选择CUDA版本。必须记住的一点是默认pip从PyPI装的torch是CPU版本直接跑在GPU上会报错说明没有可用设备。正确做法是先去PyTorch官网查看最新稳定版对应的CUDA版本然后按官网给的命令安装例如CUDA 12.1的安装命令pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121装完之后再装sentence-transformers本体这时pip检测到torch已经存在且满足要求就不会重复下载了。如果你想确认torch能不能用GPU可以执行python -c import torch; print(torch.cuda.is_available())输出True即表示GPU可用。提示如果本来没有GPU需求就不要额外装CUDA版本的torch会导致包体积增加很多还会在无GPU机器上报一堆和CUDA runtime相关的警告。3.5 验证环境隔离的效果装完都说成功了怎么证明这个环境是真的隔离的呢最简单的方法是查看当前环境的site-packages路径以及对比一下和全局环境的区别python -c import site; print(site.getsitepackages()) which python which pipwhich python输出的路径一定会包含st-env这一段字符。如果你直接执行pip --version也会发现pip本身来自这个环境目录。此时你在全局系统里无论怎么污染环境都不会影响当前项目里跑着的sentence-transformers。这个验证步骤我每次都会做一遍不是形式主义而是真的遇到过同事跑完安装命令后来找我排查为什么装不上最后发现是终端还停留在base环境没激活。4. 实操用uv快速搭建隔离环境并安装sentence-transformers如果你不习惯conda这种偏重量级的工具或者手头有多个项目频繁要切换环境uv这条路径值得认真试试。4.1 安装uv并准备pyproject.tomluv的安装方式很简单macOS和Linux下curl -LsSf https://astral.sh/uv/install.sh | sh装完重启终端验证一下uv --versionuv推荐用项目维度来管理环境而不是像conda那样手动建一个命名环境然后到处激活。所以你需要在项目文件夹下创建一个pyproject.toml文件最简单的写法[project] name st-demo version 0.1.0 requires-python 3.10,3.12 dependencies [sentence-transformers]如果只是想临时用也可以不建文件直接用命令在任意目录创建虚拟环境uv venv st-env这里st-env是目录名创建后里面就是一个独立的虚拟环境。激活方式和venv几乎一样source st-env/bin/activate4.2 用uv安装依赖如果刚才创建了pyproject.toml那么在同一个目录下直接执行uv syncuv会读取pyproject.toml里的依赖自动创建.venv目录并把sentence-transformers以及它依赖的所有包都装好。这个过程的体验比pip好不少——因为它有全局缓存像torch这种几百MB的大包如果之前装过的版本完全一致会直接命中缓存安装几乎是秒完成的。如果没有pyproject.toml也可以直接uv pip install sentence-transformers需要注意的是uv pip install会默认装进当前激活的虚拟环境所以如果你习惯手动激活记得先source st-env/bin/activate。4.3 uv切换虚拟环境的常用姿势在很多教程里会看到uv切换虚拟环境这个词它做的事情其实和conda的conda activate是同一个目的但实现方式不太一样。uv本身不维护一个环境列表它的虚拟环境就是项目里的一个目录默认叫.venv所以切换环境等于切到对应项目目录然后激活那个目录里的环境。日常做法是cd 项目A source .venv/bin/activate # 工作完去项目B deactivate cd 项目B source .venv/bin/activate如果你不想手动敲source这一长串也用direnv这类工具在进入目录时自动加载环境。说实话配置好一次之后这种目录即环境的模式比conda的命名环境更直观也不会出现我明明激活了A环境怎么python还是系统的那一个这种烦人事。4.4 在uv环境里跑通sentence-transformers安装完成后同样做一个最小验证python -c from sentence_transformers import SentenceTransformer; model SentenceTransformer(all-MiniLM-L6-v2); emb model.encode(hello world); print(emb.shape)这一步会去HuggingFace Hub下载一个小模型约80MB然后编码一个句子输出向量的形状正常是(1, 384)。能跑通这个就说明环境、依赖、模型下载链路都没问题。这里有一个国内用户经常会卡的坑HuggingFace域名在大陆地区经常连接超时导致模型下载不到。解决办法有两种一是把huggingface_hub的默认endpoint换掉设置环境变量HF_ENDPOINThttps://hf-mirror.com二是用export HF_HUB_OFFLINE1只使用本地已有模型。前一种对在线下载友好后一种适合模型已经缓存好了、想离线使用的情况。这两个环境变量放在激活环境后的终端里执行就行export HF_ENDPOINThttps://hf-mirror.com镜像站的原理很简单它把HuggingFace的模型仓库定时同步一份由于本身在国内连接速度和稳定性都会好很多。这也是社区常用的模式大家在博文里或群聊里分享模型下载技巧时很多都默认提到这个方案。5. 安装完必做的验证与实操测试装库不是终点能稳定用起来才算成功。这一节我会给你一套完整的验证流程按顺序执行一遍基本能把环境里的地雷都排掉。5.1 检查关键依赖版本是否匹配sentence-transformers对torch和transformers的版本范围有要求。实际操作中常见的一种问题就是环境里原本已经装了一个很老的transformers版本sentence-transformers安装时虽然会把依赖拉起来但可能不会强制升级到它要的版本这时跑代码会报ImportError或者一些奇怪的属性不存在。验证方法很简单pip list | grep -E torch|transformers|sentence一个我自己习惯的对照是torch 2.x配transformers 4.30以上基本是安全的如果看到torch只有1.13建议直接升级因为新版模型多数都用到了更新的API。5.2 加载模型并编码句子的最小Demo下面这段代码建议你保存成一个脚本运行一次from sentence_transformers import SentenceTransformer model SentenceTransformer(all-MiniLM-L6-v2) sentences [ 今天天气很好, 虚拟环境隔离安装工具库, 这是一个用于测试的句子, ] embeddings model.encode(sentences) print(embeddings.shape) print(embeddings[:2]) # 看看向量前两行数据你会看到输出里有一个[3, 384]的形状也就是三句话各生成了384维的向量。到这里环境安装已经真正跑通了。5.3 验证当前环境是虚拟环境而不是全局环境这一步主要是为了防止日后的误操作which python pip --version在conda环境里python路径指向/path/to/miniconda3/envs/st-env/bin/python在uv环境里路径指向项目下的.venv/bin/python。如果显示的是/usr/bin/python或者/Library/Frameworks/Python.framework/...那你肯定没激活成功。还有一个更隐蔽的操作细节激活了conda环境再用pip安装和直接用conda install安装效果是不同的。conda install装的是conda自己管理的包pip install装的是pip管理的包两者如果不注意混用偶尔会把包状态搞乱。我在用conda环境时如果sentence-transformers及其依赖都用pip装后面升级也用pip就不要频繁切换包管理器这是踩过一次坑总结出的习惯。5.4 模型缓存的存放位置与管理sentence-transformers在首次加载模型时会把模型文件缓存到本地。默认缓存目录是~/.cache/huggingface/hub/你可以通过环境变量HF_HOME或SENTENCE_TRANSFORMERS_HOME来指定export HF_HOME/path/to/your/hf_cache为什么要单独指定因为如果你用conda创建了很多环境多个环境共用同一个缓存磁盘占用可以省下很多而如果你给每个环境独自指定一个缓存目录则每个环境都会各存一份模型文件很快就把磁盘撑满。就我的经验来说建议所有环境共用同一个HF_HOME因为模型文件的加载不会因为环境隔离受影响。查看缓存内容的方式ls -l ~/.cache/huggingface/hub里面每个模型一个目录命名格式是models--microsoft--MiniLM-L6-H384-uncased这类。如果磁盘紧张可以把不用的模型目录整个删掉下次再用时会重新下载。6. 常见坑与故障排查虚拟环境装库这件事说难不难说简单也总有那么几个高频问题。我把自己见过的或者被问过的故障整理了一下给出一条完整的排查链路。6.1 装完sentence-transformers之后import报错Segmentation fault这个问题我在多台机器上都遇到过尤其是之前全局环境有过旧版numpy或者torch的环境再在虚拟环境里装新包后import时出现段错误。根因通常是当前环境链接到了系统里一个不兼容的OpenMP库torch在加载时会冲突。排查思路先用python -c import torch确认torch单独能不能导入如果不能说明问题不在sentence-transformers在torch本身的安装或动态库链接如果能再python -c from sentence_transformers import SentenceTransformer看是在哪一步崩掉如果确认是OpenMP冲突可以尝试设置环境变量KMP_DUPLICATE_LIB_OKTRUE临时绕过这个方法在macOS上尤其有效或者用conda重装一个干净的numpy和torch组合。6.2 下载模型超时或断断续续这个问题前面提过核心就是HF域名连接不稳。处理手段不复杂设一下环境变量用镜像就行export HF_ENDPOINThttps://hf-mirror.com如果要永久生效建议写进shell的配置文件里比如~/.bashrc或~/.zshrc这样每次进环境都自动生效。需要注意HF_ENDPOINT这个变量只影响huggingface_hub库的默认endpoint不影响其他网络请求。6.3 虚拟环境迁移时模型路径失效有朋友试过把整个conda环境从一台机器复制到另一台机器结果模型中总是报路径找不到。原因是环境里的绝对路径变了包括Python解释器路径、pip路径以及缓存路径。此时建议新机器上不要试图直接复制环境目录而是在新机器上重建同样版本的环境后再重新拉取依赖和模型。如果确实需要离线迁移可以用conda-pack把整个环境打包成一个tar.gz文件再拷到新机器解压。但要注意打包前环境里的所有模型文件不会自动包含进去模型还是要额外拷贝HF_HOME目录过去。6.4 pip提示externally-managed-environment错误这个错误主要是较新版本Python3.11及以上在Debian/Ubuntu系统上会遇到的。系统层面的pip会提示环境由操作系统管理不允许直接往系统环境里装包。这不是bug而是为了阻止你污染系统Python。解决办法分两类如果你已经在虚拟环境里这个错误理论上不会出现因为虚拟环境不归系统管如果出现了说明你没激活虚拟环境或者激活后pip命令还是解析到了系统的pip。检查一下which pip确认路径在虚拟环境内。6.5 CUDA版本和torch版本不匹配在GPU机器上安装时最容易遇到的就是装完torch后运行报CUDA driver version is insufficient for CUDA runtime version。这通常是因为pip装的torch在编译时选择了较高的CUDA版本而你的显卡驱动版本太老。解决办法先执行nvidia-smi看driver支持的CUDA版本再根据这个版本去PyTorch官网选择对应的安装命令。如果驱动太旧可能需要升级NVIDIA驱动。不要图省事直接装最新版CUDA的torch那大概率会跑不起来。7. 隔离环境下的进一步优化好不容易把环境建好、装好了为了让日常使用更顺手还有几个优化操作值得做。7.1 把依赖锁定成文件方便复现如果你用的是uv可以把当前环境的依赖导出为requirements文件uv pip freeze requirements.txt如果是conda环境导出pip依赖也一样pip freeze requirements.txt下次要复现同样的环境时在新的虚拟环境里执行pip install -r requirements.txt即可。锁文件的另一个好处是新同事或新机器上配环境时不会因为某个依赖小版本更新而出现莫名其妙的不兼容。7.2 为Jupyter Notebook配置内核如果你在虚拟环境里装好了库但打开Jupyter却发现import不到原因多半是你没把这个环境注册为kernel。注册方法很简单pip install ipykernel python -m ipykernel install --user --name st-env --display-name Python (st-env)这样Jupyter的kernel列表里就会多出一个Python (st-env)选择它以后Notebook内部运行的代码就会走这个虚拟环境的解释器。7.3 清理不再需要的环境与缓存虚拟环境的好处就是删除成本低conda环境conda env remove -n st-envuv/venv环境直接rm -rf .venv st-env清理完环境以后如果磁盘占用仍然很高可以顺手清一下pip/uv的缓存因为大模型的轮子包动辄几百MB攒多了非常占空间。conda可以跑conda clean --alluv可以跑uv cache clean。7.4 用环境变量管理模型和数据集下载位置我现在的惯用配置是在shell配置文件里统一设置export HF_HOME$HOME/.cache/huggingface export HF_ENDPOINThttps://hf-mirror.com export TOKENIZERS_PARALLELISMfalseTOKENIZERS_PARALLELISMfalse这个变量很多人会忽略它可以在多进程数据处理时避免tokenizers库输出一堆并发警告。设置完之后无论创建多少个虚拟环境模型下载位置和镜像策略都是一致的。最后再分享一个我实际操作中的体会虚拟环境隔离这件事不怕多建几个环境就怕建得随意、用完不清理。我给每个项目单独建环境命名规则统一是项目名-env用完就删。如果临时试验某个库的可行性就用uv建一个临时目录测完直接丢掉完全不影响手头正在做的正事。这套习惯坚持下来之后装库这件事基本不会成为开发链路里的瓶颈。
返回列表