spaCy 2.2.5 模型包 en_core_web_sm-2.2.5 安装与 NER 实战避坑指南
发布时间:2026/10/8 2:59:16 锦皓数字建站

简介en_core_web_sm-2.2.5.tar.gz 是 spaCy 官方发布的英文小型预训练模型离线安装包面向从事自然语言处理的数据科学从业者、Python 开发者及 NLP 初学者用于解决官网下载受限时无法直接获取模型的问题。该模型支持英文分词、词性标注、依存句法分析与命名实体识别等基础任务适合内存有限或对推理速度要求较高的场景。压缩包共 30 个文件约 11.46MB内含 json 配置与元数据、txt 说明文档、cfg 参数文件、model 权重文件、bin 二进制数据以及 py 脚本等覆盖模型加载与运行所需的完整组件。目前已有 1232 人学习下载。通过该资源读者可离线完成模型安装与加载快速跑通分词、实体识别和句法分析示例并理解 small 版本在精度与资源消耗之间的取舍为后续选用更大模型或训练自定义模型打下基础。1. 从一次版本锁死说起为什么我还在用 en_core_web_sm-2.2.5上周帮同事排查一个线上 NER 服务报错日志里赫然写着Cant find model en_core_web_sm。他本地跑得好好的一到容器里就崩。翻了他的 requirementsspaCy 锁的是 2.2.x但模型装的是最新版 3.x 的en_core_web_sm版本对不上加载直接失败。这种翻车现场我见过太多次了。en_core_web_sm-2.2.5.tar.gz就是 spaCy 2.2.5 配套的英文小模型包里面装着分词、词性标注、依存句法、命名实体识别这几条 pipeline 的权重和词表。它解决的不是能不能做 NLP的问题而是在锁定 spaCy 2.2.5 的老项目里怎么让 pipeline 正常加载的问题。适合谁维护历史项目的人、复现老论文的人、以及被版本兼容性折磨过的工程师。如果你正在用 spaCy 3.x这篇对你参考有限但如果你手上有个跑了两三年、动不了 spaCy 版本的服务那这个包就是你的后悔药。2. 拆开 tar.gz模型包里到底装了什么2.1 目录结构与关键文件拿到en_core_web_sm-2.2.5.tar.gz之后别急着pip install先解压看一眼。我一般会先tar -tzf列一下内容确认包没损坏、结构对得上。# 列出压缩包内容不实际解压 tar -tzf en_core_web_sm-2.2.5.tar.gz | head -30典型输出会包含这几类东西路径作用en_core_web_sm-2.2.5/setup.py安装脚本声明包名和依赖en_core_web_sm-2.2.5/en_core_web_sm/__init__.py模型加载入口load()从这里走en_core_web_sm-2.2.5/en_core_web_sm/meta.json元信息记录 spaCy 版本、pipeline 组件、语言en_core_web_sm-2.2.5/en_core_web_sm/tokenizer/分词器配置和词表en_core_web_sm-2.2.5/en_core_web_sm/vocab/词向量和哈希表en_core_web_sm-2.2.5/en_core_web_sm/ner/命名实体识别模型权重en_core_web_sm-2.2.5/en_core_web_sm/parser/依存句法分析模型en_core_web_sm-2.2.5/en_core_web_sm/tagger/词性标注模型meta.json是最该先看的文件它决定了这个模型能不能被你当前的 spaCy 加载。里面有个spacy_version字段写的是2.2.2还有个pipeline数组列出tagger、parser、ner三个组件。如果你装的 spaCy 是 3.x这个 meta 里的版本约束就会让加载失败——不是模型坏了是版本契约不匹配。2.2 为什么是 sm 而不是 md/lgspaCy 的英文模型分 sm、md、lg 三档。sm 没有词向量或者只有很小的向量表md 和 lg 带完整的 300 维 GloVe 向量。en_core_web_sm的体积通常在 10MB 出头加载快、内存占用低适合做 pipeline 里的标注任务不适合做语义相似度。很多人踩的坑是拿 sm 去做doc.similarity()结果发现相似度全是 0 或者毫无意义。这不是 bug是 sm 本来就没向量。如果你需要向量得换 md 或 lg或者自己接一个向量源。选型逻辑很简单做 NER、POS、依存句法sm 够用做语义匹配、文本聚类别用 sm。2.3 安装方式pip install 直接吃 tar.gz这个包不需要解压后再装pip 可以直接从 tar.gz 安装。这是最省事的路径# 确认当前 spaCy 版本必须是 2.2.x python -c import spacy; print(spacy.__version__) # 直接从 tar.gz 安装模型 pip install en_core_web_sm-2.2.5.tar.gz # 验证安装 python -c import en_core_web_sm; nlp en_core_web_sm.load(); print(nlp.pipe_names)pip install后面跟本地 tar.gz 路径pip 会调用包里的setup.py完成安装。安装完成后en_core_web_sm就变成一个可导入的 Python 包。nlp.pipe_names应该输出[tagger, parser, ner]如果输出空列表或者报错说明安装有问题。参数说明spacy.__version__必须匹配2.2.x。如果你看到3.x先降级 spaCy 再装模型否则后面加载必挂。降级命令是pip install spacy2.2.5但注意这会连带影响其他依赖建议在虚拟环境里操作。3. 加载与推理从 load() 到实体抽取的完整链路3.1 load() 的两种写法与差异装好之后加载模型有两种写法。第一种是直接 import 包再 loadimport en_core_web_sm nlp en_core_web_sm.load() doc nlp(Apple is looking at buying U.K. startup for $1 billion) for ent in doc.ents: print(ent.text, ent.label_)第二种是通过 spaCy 的spacy.load()按名称加载import spacy nlp spacy.load(en_core_web_sm) doc nlp(Apple is looking at buying U.K. startup for $1 billion) for ent in doc.ents: print(ent.text, ent.label_)两种写法在 2.2.5 里等价但有个细节spacy.load()会走 spaCy 的模型发现机制如果环境里有多个版本的en_core_web_sm可能加载到不是你预期的那个。en_core_web_sm.load()更直接绑定到你安装的那个包。我一般在容器里用第二种避免玄学问题。输出应该是Apple ORG U.K. GPE $1 billion MONEY如果doc.ents是空的先检查nlp.pipe_names里有没有ner。没有的话说明模型加载时 pipeline 被禁用了可能是load(disable[ner])传了参数或者 meta.json 里的 pipeline 配置被改过。3.2 批量推理nlp.pipe 的正确用法单条推理够用但线上服务都是批量的。spaCy 提供了nlp.pipe()比循环调用nlp()快得多因为它内部做了批处理。import spacy nlp spacy.load(en_core_web_sm) texts [ Apple is looking at buying U.K. startup for $1 billion, Google was founded in September 1998, Teslas stock rose 5% on Monday, ] # batch_size 控制每批处理的文档数n_process 控制并行进程数 for doc in nlp.pipe(texts, batch_size50, n_process2): print([(ent.text, ent.label_) for ent in doc.ents])batch_size默认是 1000对小文本可以调小到 50 左右减少内存峰值。n_process在 2.2.5 里支持多进程但注意多进程会复制模型到每个进程内存占用翻倍。如果模型是 sm影响不大如果是 lg慎用。还有一个坑n_process 1时spaCy 会用multiprocessing在某些容器环境里会卡死原因是/dev/shm太小。解决办法是设n_process1或者给容器加--shm-size。3.3 抽取结果的结构化输出NER 抽出来的实体直接 print 只能看要落库或传给下游得结构化。我一般会转成列表套字典import spacy import json nlp spacy.load(en_core_web_sm) def extract_entities(text): doc nlp(text) return [ { text: ent.text, label: ent.label_, start: ent.start_char, end: ent.end_char, } for ent in doc.ents ] result extract_entities(Apple is looking at buying U.K. startup for $1 billion) print(json.dumps(result, ensure_asciiFalse, indent2))start_char和end_char是实体在原文里的字符偏移做高亮或回标时很有用。注意spaCy 的偏移是基于 Unicode 字符的不是字节。如果原文里有中文或 emoji偏移计算和 Python 字符串索引一致不用额外转换。但如果你把文本存到数据库再取出来编码变了偏移可能对不上这是常见坑。4. 避坑与排查版本、内存、多进程的五个血泪教训4.1 现象加载报错 Cant find model en_core_web_sm原因spaCy 版本和模型版本不匹配。spaCy 3.x 的spacy.load()不认 2.x 的模型包反之亦然。或者模型装了但不在当前 Python 环境的 site-packages 里。解决先pip show spacy看版本再pip show en_core_web_sm看模型版本。两个版本必须同属 2.2.x。如果版本对但还报错用python -c import en_core_web_sm; print(en_core_web_sm.__file__)确认包路径看是不是装到了别的环境。4.2 现象doc.ents为空但文本里明明有实体原因pipeline 里ner组件被禁用了。可能是加载时传了disable[ner]或者模型包的 meta.json 里 pipeline 配置被改过。解决print(nlp.pipe_names)确认组件列表。如果是空的重新安装模型包别手动改 meta.json。如果列表里有ner但实体还是空检查文本语言——sm 模型只支持英文中文文本进去实体识别基本失效。4.3 现象多进程推理时进程卡死CPU 占用为 0原因容器/dev/shm默认 64MBspaCy 多进程通信时共享内存不够进程阻塞。解决设n_process1先跑通或者给容器加--shm-size1g。如果必须多进程用n_process2起步观察内存和 CPU。另一个办法是用nlp.pipe()的batch_size调大减少进程间通信频率。4.4 现象内存持续增长跑几万条后 OOM原因nlp.pipe()默认会把所有 doc 缓存在内存里如果没及时释放越跑越大。或者n_process 1时每个进程都复制了一份模型。解决用生成器消费nlp.pipe()处理完一条丢一条别攒成列表。代码示例for doc in nlp.pipe(texts, batch_size50): entities [(ent.text, ent.label_) for ent in doc.ents] # 立即处理 entities不要存 doc 对象 save_to_db(entities)doc对象持有 token 和标注信息比原文大很多倍。存 doc 等于存了膨胀后的数据内存不炸才怪。4.5 现象相似度计算全是 0 或随机值原因en_core_web_sm没有词向量doc.similarity()走的是 token 的哈希向量结果没有语义意义。解决换en_core_web_md或en_core_web_lg或者自己接一个向量模型。如果只是做实体抽取忽略相似度就行。别在 sm 上纠结相似度这是模型设计决定的不是配置问题。5. 进阶技巧把 sm 模型塞进 FastAPI 并做版本自检5.1 用 FastAPI 包一层推理接口线上服务不会让你直接调 Python 脚本一般会包成 HTTP 接口。FastAPI 是最轻的选择配合 uvicorn 跑起来很快。from fastapi import FastAPI from pydantic import BaseModel import spacy app FastAPI() nlp spacy.load(en_core_web_sm) class TextRequest(BaseModel): text: str class Entity(BaseModel): text: str label: str start: int end: int app.post(/extract, response_modellist[Entity]) def extract(req: TextRequest): doc nlp(req.text) return [ Entity(textent.text, labelent.label_, startent.start_char, endent.end_char) for ent in doc.ents ]启动命令uvicorn main:app --host 0.0.0.0 --port 8000。请求示例curl -X POST http://localhost:8000/extract -H Content-Type: application/json -d {text: Apple is looking at buying U.K. startup}。注意spacy.load()在模块加载时执行一次全局复用。别在接口函数里反复 load那样每次请求都重新加载模型性能直接崩。5.2 启动时做版本自检模型版本和 spaCy 版本不匹配是最高频的翻车点。我习惯在服务启动时加一段自检不匹配就直接退出别等请求进来才报错。import spacy import en_core_web_sm import sys def check_versions(): spacy_version spacy.__version__ model_meta en_core_web_sm.load().meta model_spacy_version model_meta.get(spacy_version, unknown) print(fspaCy version: {spacy_version}) print(fModel requires spaCy: {model_spacy_version}) if not spacy_version.startswith(2.2): print(ERROR: spaCy version mismatch, expected 2.2.x) sys.exit(1) if 2.2 not in model_spacy_version: print(ERROR: model version mismatch) sys.exit(1) check_versions()这段代码在服务启动时跑一遍版本不对直接sys.exit(1)容器编排会重启或告警比等到线上请求失败再排查快得多。model_meta里的spacy_version字段是模型包声明的最低兼容版本实际运行时 spaCy 版本必须满足这个约束。5.3 一个验证清单部署前我会走一遍这个清单确认模型真的能用检查项命令预期spaCy 版本python -c import spacy; print(spacy.__version__)2.2.x模型可导入python -c import en_core_web_sm; print(ok)okpipeline 组件python -c import en_core_web_sm; print(en_core_web_sm.load().pipe_names)[tagger, parser, ner]实体抽取python -c import en_core_web_sm; nlpen_core_web_sm.load(); print(nlp(Apple is in U.K.).ents)至少两个实体批量推理跑 100 条文本观察内存内存稳定无 OOM这个清单不复杂但能挡住八成以上的部署问题。从那以后我每次上线前都强制走一遍版本自检和这个清单再也没出现过本地能跑、线上报错的尴尬。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。