公司动态
本地模型实现信息抽取:从选型到工程落地全指南
过去两年只要提到“信息抽取”绝大多数团队的第一反应都是把文本丢给云端大模型 API等着拿回 JSON。这个流程确实好用但它默认了一个前提——你的数据允许上传到第三方服务器。一旦数据涉及内部业务、客户隐私、审计留痕或者干脆要部署在无外网的机房这条路就断了。于是“本地模型能不能做抽取”成了越来越多团队必须回答的问题。这篇文章想给一个明确的判断本地模型做抽取任务已经不是“能不能用”的问题而是“怎么选、怎么调、怎么兜底”的问题。它在隐私、成本、可定制性上有不可替代的优势但它的坑也很真实——Prompt 稍微写含糊输出就不稳定模型选小了准确率直接崩选大了显存又扛不住。本文会从抽取任务的基础认知、本地模型选型、部署环境、Prompt 设计与代码实现、结果验证和工程落地方案完整展开帮你把这条链路走通。如果你正在做文档信息抽取、结构化数据构建、建筑与地理信息相关的属性抽取或者只是好奇本地模型和云端 API 到底该怎么选这篇文章值得读完。1. 这篇文章真正要解决的问题很多人对“本地模型做抽取”有一个误解以为把云端 API 换成开源的模型权重改一下base_url剩下的事就水到渠成。真正动手后才发现问题不是“模型能不能跑”而是同一个 Prompt 在云端 API 上稳定输出 JSON换成本地小模型就频繁漏字段、套壳输出、甚至直接说“我不会”模型量化版本选错了回答质量下降明显但显存占用少得有限本地模型没有云端 API 那么好用的函数调用和结构化输出能力必须自己设计 JSON Schema、做后处理抽取结果没有置信度错误数据直接进数据库后续校验成本反而更高。这篇文章要解决的就是这些具体问题。我从结论说起本地模型做抽取真正的价值不在于“模型本身多聪明”而在于它让抽取这条流水线变得可落地、可审计、可离线、可长期用。它的核心壁垒不是算法而是工程——包括 Prompt 设计、输出约束、结果校验和失败重试机制。什么类型的读者最应该看做 RPA、文档数字化、知识图谱构建的开发者需要批量从非结构化文本里抽实体和关系在地理信息、遥感、建筑行业做数据处理的工程师需要从规划文档、勘察报告、GIS 元数据里抽取建筑属性信息做内部数据平台数据不允许出内网但希望用上大模型能力的团队。如果你是这几类人这篇文章会给你一条完整的落地路径。2. 信息抽取任务与本地模型的基础认知2.1 信息抽取到底在抽什么信息抽取Information ExtractionIE是把非结构化或半结构化文本转换为结构化数据的任务。最常见的子任务包括子任务英文说明命名实体识别NER从文本中识别出人名、地名、机构名、时间、金额等实体关系抽取RE判断两个实体之间的关系例如“张伟是项目负责人”事件抽取EE抽取事件触发词、事件类型、参与者和时间地点属性抽取Attribute Extraction抽取实体的属性例如建筑的面积、层数、建造年份一项现实的抽取任务往往是这些子任务的组合。例如从一份建筑勘察报告里抽取“项目位置、建筑面积、建筑类型、当前状态”本质上是先做实体识别再做属性填充最后输出成 JSON。传统做法是训练专门的 NER 模型加规则模板成本高且维护周期长。云端大模型改变了这个局面但引入了数据出域问题。本地模型则是对这两条路线的一个折中既能靠自然语言 Prompt 快速适配新任务又能把数据留在自己的机器上。2.2 building footprint extraction 到底是什么任务这里要澄清一个常见混淆。网络上经常会看到 building footprint extraction建筑足迹提取这个热词它指的是从遥感影像中提取建筑轮廓属于计算机视觉里的语义分割或实例分割任务直接产出的是矢量多边形或掩膜而不是文字。它和信息抽取是两个方向但都属于“从原始数据里提取结构化信息”的范畴。在 GeoAI 落地项目里常见的工作流是先用视觉模型从影像中提取建筑轮廓再用 NLP 模型从规划文本、权属材料里抽取建筑的属性信息最终把几何信息和属性信息合并成完整的建筑数据库。所以当你搜索 Local models extraction 相关技术方案时需要先确认自己要做的是图像轮廓提取还是文本属性抽取。本文后续内容主要聚焦文本信息抽取方向但在工程架构上这两条链路都适合接入本地模型。2.3 本地模型与云端 API 的对比对比维度云端大模型 API本地开源模型数据安全数据需发送到第三方服务器数据不出本机或内网初始成本按 Token 付费长期累计成本高需要 GPU 硬件投入部署复杂度低几行代码接入较高需环境配置和模型管理可定制性依赖平台功能可微调、可量化、可换模型稳定性平台维护稳定性较好依赖自身运维能力离线可用不支持支持延迟受网络和平台负载影响本地推理延迟可控这个对比想说明一个点本地模型不是全面替代云端 API而是在“数据敏感、成本敏感、需要离线”的场景里成为更优解。很多团队的做法是云端模型做冷启动验证本地模型做生产环境服务两者通过统一的接口抽象切换。2.4 为什么抽取任务适合本地模型抽取任务有一个特点实体类型和输出格式高度固定。某个项目里可能只需要抽取“地点、建筑面积、建筑类型、用途状态”这几个字段。这类任务对模型的“常识广度”要求不高但对“指令跟随能力”和“格式稳定性”要求很高。这正好落在开源本地模型的能力射程内。一个 7B 到 14B 参数量的开源模型经过合适的 Prompt 约束和 JSON Schema 引导完全可以在限定领域的抽取任务上达到可用水平。这也解释了为什么当前本地模型最活跃的应用方向之一就是结构化抽取——它是“模型能力有限但任务边界清晰”的最佳组合。3. 本地模型选型从哪个模型开始3.1 开源本地模型的常见选择目前主流的开源本地模型系列主要有几个方向我这里不做跑分排名只给选型思路Qwen 系列通义千问开源版中文抽取能力表现出色对中文长文本和结构化输出支持较好是目前国内团队最常用的本地模型之一。Llama 系列Meta 开源社区生态最丰富几乎支持所有推理框架适合作为底座做微调但中文能力通常需要补充训练。Mistral 系列欧洲团队开源英文能力强上下文窗口和指令跟随能力优秀但在中文场景下应用不如 Qwen 方便。如果你处理的是中文文本从 Qwen 系列开始是更稳妥的选择如果业务面向英文且需要更强的推理能力Llama 和 Mistral 也值得测试。3.2 参数量怎么选这可能是选型中最重要的一个决策。参数量级建议显存适用场景3B4B4GB8GB简单实体抽取、格式固定、对准确率要求不极高7B8B8GB16GB大多数信息抽取任务平衡准确率和资源消耗14B16GB32GB复杂关系抽取、长文档、需要更强指令跟随32B 以上32GB 以上或需量化高难度抽取、多语言、需要接近云端 API 效果真实项目中我推荐先按“任务复杂度 显存上限”确定参数量而不是先追求大模型。原因很直接抽取任务通常可以拆成多个小任务拆完之后7B 模型往往就够用了。如果一开始就上 32B 模型部署成本高不说推理延迟也会制约批处理效率。3.3 量化版本要不要用量化Quantization是把模型参数从 16 位浮点数压缩到 8 位或更低以减少显存占用、提高推理速度但会带来少量精度损失。对抽取任务我的建议是先用原版精度跑通基准测试确认准确率达标再尝试 Q4 或 Q5 量化对比输出质量。如果量化后的结果没有明显变差就可以用量化版本部署因为它的显存占用和推理成本会低很多。这里有一个值得注意的坑量化版本在大部分简单抽取任务上没有差异但在长文本、复杂指令或多语言混合的场景下可能出现“字段输出不完整”“格式偶尔跑偏”等问题。因此量化后的效果验证绝对不能省。4. 本地部署环境准备4.1 推理框架选哪个当前部署本地模型常用的推理方案有三个按易用性排序Ollama安装简单模型管理方便自带 OpenAI 兼容 API适合个人和中小团队快速验证。llama.cpp底层的 C/C 推理框架适合嵌入式环境和极致性能调优。vLLM吞吐高适合生产环境大规模并发推理但部署复杂度更高。本文以 Ollama 为主线因为它能最快跑通完整链路也最符合“从零到一”演示需求。生产环境需要高并发时可以迁移到 vLLM——代码改动幅度很有限。4.2 安装 OllamaOllama 支持 Windows、Linux 和 macOS。Linux 和 macOS 可以执行官方安装脚本curl -fsSL https://ollama.com/install.sh | shWindows 用户下载安装包安装即可。安装完成后检查版本ollama --version启动服务ollama serve在 Linux 上Ollama 安装后通常会注册为 systemd 服务可以通过ollama serve手动启动方便观察日志。4.3 下载并运行模型以 Qwen 系列 7B 模型为例在终端执行ollama run qwen2.5:7b首次运行会先下载模型权重完成后进入交互式对话界面可以直接输入文本测试。到这里本地模型已经跑起来了。这一步的关键是确认模型标签在本机真实存在。可以用以下命令查看已下载的模型ollama list如果你不确定某个标签是否存在可以在模型库页面确认名称或直接使用ollama pull qwen2.5:7b拉取。5. 核心流程用本地模型做抽取任务5.1 先设计任务再写 Prompt很多人做抽取任务一上来就写 Prompt这是一个误区。先要明确“输出 Schema”也就是你希望模型输出什么结构的数据。例如要从建筑勘察文本中抽取属性最简单的 Schema 是{ location: 项目地点, building_type: 建筑类型, area: 建筑面积, status: 当前状态 }Schema 决定了 Prompt 里的“输出要求”部分。Schema 设计得越清晰后续解析和校验越简单。5.2 本地抽取的 Prompt 设计原则针对本地模型Prompt 设计有四个原则第一身份与任务要具体。不要写“你是一个助手”要写“你是建筑信息抽取助手负责从文本中抽取指定字段”。第二输出格式要显式。直接给出 JSON 示例比单纯说“输出 JSON”有效得多。本地模型对示例的模仿能力很强宁可多花几行 token也要在 Prompt 里放一个完整的输出示例。第三指定缺失处理。告诉模型“如果某个字段没有找到输出空字符串或 null”避免模型自己编造内容。这一步是抽取任务里最容易出问题的地方。第四保持温度低。抽取是确定性任务temperature 建议设置为 0抑制随机性。5.3 Prompt 模板示例下面是一个适合本地模型的抽取 Prompt 模板你是建筑信息抽取助手。请从用户提供的文本中抽取以下字段 - location项目地点 - building_type建筑类型 - area建筑面积保留数字 - status当前状态如已建成、在建、规划中 要求 1. 只输出 JSON 对象不要输出任何解释文字。 2. 字段未找到时输出 null不要编造。 3. 面积统一使用单位“平方米”。 示例输出 {location: 上海市浦东新区, building_type: 研发大楼, area: 12000, status: 在建}这个模板的关键在于“只输出 JSON”和“未找到时输出 null”它们能显著提高后续解析的成功率。5.4 输出后处理与校验即便 Prompt 写得再好本地模型仍然可能输出 Markdown 代码块、多余解释、或者字段名跑偏。因此后处理是必须的不能跳过。后处理通常包括三步去掉 Markdown 代码块标记用json.loads解析失败时进入重试用 JSON Schema 校验字段是否齐全缺失的字段标记为 null。这套后处理逻辑虽然简单但它决定了整个抽取流水线的稳定性。生产环境下建议把“解析失败”和“字段缺失”统计成指标用于衡量模型的实际效果。6. 完整示例代码实现6.1 安装依赖需要安装 Ollama 的 Python 库以及用于测试的 OpenAI SDK。pip install ollama openai如果后续要切换到 vLLM 或其他 OpenAI 兼容服务openai这个依赖会非常有用。6.2 示例一使用 Ollama Python 库做实体抽取新建文件extract_entities.py代码如下# 文件路径extract_entities.py import ollama response ollama.chat( modelqwen2.5:7b, messages[ { role: system, content: ( 你是信息抽取助手。请从用户输入文本中抽取实体 并输出 JSON 对象字段包括person、organization、 location、date。没有找到的字段输出空列表。 ), }, { role: user, content: ( 2024年6月绿城建筑公司在杭州完成了智慧园区项目的验收 项目负责人是张伟验收日期是6月28日。 ), }, ], formatjson, ) print(response[message][content])运行验证python extract_entities.py预期输出是一个 JSON 对象例如{ person: [张伟], organization: [绿城建筑公司], location: [杭州], date: [2024年6月, 6月28日] }这里formatjson参数会让 Ollama 尽量以 JSON 格式输出能大幅度降低解析难度。6.3 示例二使用 OpenAI 兼容接口抽取建筑属性Ollama 启动后默认在11434端口提供 OpenAI 兼容 API可以用标准 OpenAI SDK 调用方便以后切换后端。新建文件extract_building.py# 文件路径extract_building.py from openai import OpenAI client OpenAI( base_urlhttp://localhost:11434/v1, api_keyollama, # 本地服务不校验真实 key但字段不能为空 ) resp client.chat.completions.create( modelqwen2.5:7b, temperature0, response_format{type: json_object}, messages[ { role: system, content: ( 你是建筑信息抽取助手。请从文本中抽取字段location、 building_type、area、status。只输出 JSON不要输出解释。 ), }, { role: user, content: ( 上海市浦东新区张江科技园的研发大楼建筑面积约12000平方米 目前正在建设中。 ), }, ], ) print(resp.choices[0].message.content)运行验证python extract_building.py预期输出{ location: 上海市浦东新区张江科技园, building_type: 研发大楼, area: 12000, status: 在建 }这个示例的关键点是base_url只要指向http://localhost:11434/v1本地模型和云端 API 的切换就只剩配置差异业务代码基本不用改。6.4 示例三批量抽取与 JSON 解析后处理真实项目中抽取往往面向批量文本。我们把后处理逻辑封装成一个函数并在循环中批量执行。新建文件batch_extract.py# 文件路径batch_extract.py import json import ollama def parse_json_response(content: str) - dict: 清理模型输出并解析 JSON解析失败时抛出异常。 content content.strip() # 去掉常见的 markdown 代码块标记 if content.startswith(): lines content.splitlines() if lines and lines[0].startswith(): lines lines[1:] if lines and lines[-1].strip() : lines lines[:-1] content \n.join(lines) return json.loads(content) def extract_fields(text: str, model: str qwen2.5:7b) - dict: 抽取文本中的建筑字段。 resp ollama.chat( modelmodel, messages[ { role: system, content: ( 抽取以下字段location、building_type、area、status。 只输出 JSON没有的信息输出 null不要编造。 ), }, {role: user, content: text}, ], formatjson, ) return parse_json_response(resp[message][content]) texts [ 北京朝阳区望京 SOHO 塔一写字楼2014年投入使用。, 成都高新区天府软件园办公园区园区面积约100万平方米。, 武汉东湖新技术开发区的地下综合管廊项目仍在规划中。, ] for text in texts: try: result extract_fields(text) print(json.dumps(result, ensure_asciiFalse)) except json.JSONDecodeError as e: print(解析失败原始输出, e)运行验证python batch_extract.py如果某条数据解析失败程序不会整体中断而是打印错误信息方便后续定位 Prompt 或模型问题。7. 运行结果与效果验证7.1 验证步骤本地模型做抽取验证不能只看一两条结果要做三件事第一准备一个测试集。至少 20 到 50 条真实业务文本覆盖正常情况、缺失字段情况、长文本情况。第二统计指标。抽取任务的常用指标是字段级准确率和字段级召回率。字段级准确率衡量“抽出来的字段是否正确”字段级召回率衡量“应该抽到的字段是否被漏掉”。第三检查失败案例。对每一条解析失败或字段错误的数据记录原因是 Prompt 不清晰还是模型能力不足还是后处理有 bug。7.2 简单评估脚本这里给一个最小评估思路# 文件路径evaluate.py import json from batch_extract import extract_fields test_cases [ { text: 上海市浦东新区张江科技园研发大楼12000平方米在建。, expected: { location: 上海市浦东新区张江科技园, building_type: 研发大楼, area: 12000, status: 在建, }, }, ] total len(test_cases) correct 0 for case in test_cases: result extract_fields(case[text]) if result case[expected]: correct 1 else: print(期望, case[expected]) print(实际, result) print(f准确率{correct}/{total})这个脚本只做说明实际项目里还需要处理字段级部分匹配和未知字段等问题但思路是一致的。7.3 失败时先看哪里如果结果不理想按以下顺序排查先看原始输出。用ollama run或脚本直接打印模型输出确认是“格式不对”还是“内容不对”。格式不对优先修 Prompt 和后处理内容不对优先换模型和调 Prompt。确认是否使用了低温度。抽取场景 temperature 必须低否则同样的输入可能输出不同结果。8. 常见问题与排查思路本地模型做抽取的坑不少这里把高频问题整理成表格。问题现象可能原因排查方式解决方案模型输出不是 JSON而是解释文字Prompt 约束不够强查看原始输出内容在 Prompt 中强调“只输出 JSON”并加示例开启 formatjson字段总是丢特别是面积、日期模型参数量小长文本注意力不足检查缺失字段是否在输入中出现拆分长文本降低单次抽取字段数或换更大模型同一个样本多次运行结果不同temperature 设置过高检查推理参数将 temperature 设置为 0启动时显存不足模型量化等级低或并发过高观察启动日志和显存占用换更小参数量模型或启用 Q4/Q5 量化首次运行很慢卡在下载模型权重未下载完成查看ollama list和网络状态确认已执行ollama pull磁盘空间充足批量处理时单条失败导致整体中断后处理没有做异常捕获查看错误堆栈对每条数据捕获json.JSONDecodeError失败时记录日志并继续本地模型准确率低于云端 API模型能力或 Prompt 设计问题做小规模对比测试先优化 Prompt 和输出约束仍不达标再换更大模型换模型后行为差异大不同模型对 Prompt 的敏感度不同对比两个模型的原始输出针对模型调整 Prompt不要期望一套 Prompt 通吃这组问题里最高频的还是“输出不稳定”和“字段缺失”。它们通常不是独立问题而是 Prompt、模型参数量、任务拆分三者共同作用的结果。建议一次只改一个变量不要同时换模型、改 Prompt、改后处理否则很难定位瓶颈。9. 最佳实践与工程建议9.1 把抽取任务拆小不要追求一次搞定本地模型的能力上限决定了一个 Prompt 里塞太多字段抽取质量会明显下降。更稳妥的做法是先抽实体再做关系或属性匹配最后拼接成结构化结果。看似多跑了几次模型但每次任务边界清晰准确率反而更高。9.2 输出 Schema 先行Prompt 与后处理共用一份定义把字段定义、JSON Schema、Prompt 模板放在一个配置文件里维护避免 Prompt 和后处理各写一份。这样字段变更时只改一处不会出现 Prompt 里写了area后处理却在找building_area的尴尬。# 文件路径schema.py EXTRACTION_SCHEMA { location: 项目地点, building_type: 建筑类型, area: 建筑面积, status: 当前状态, }9.3 建立失败样本回收机制生产环境中建议把解析失败、字段缺失、置信度不高的样本统一存储定期人工复核再把这些样本加入测试集或微调数据。这是本地模型抽取效果持续提升的最可靠路径。很多团队用久了效果变差就是因为没有做失败样本回收模型和 Prompt 都停在原地。9.4 用缓存提升批量抽取效率同一段文本被重复抽取的情况很常见。可以按文本内容哈希做结果缓存重复任务直接读取历史结果减少 GPU 占用和耗时。对于大体量历史数据处理这一步能省下大量推理成本。9.5 安全与合规提醒如果处理的数据涉及个人或敏感业务信息请确保部署环境、模型下载渠道和输出存储都符合公司内部的安全规范。本地模型虽然解决了“数据不出域”的问题但模型权重本身、Prompt 内容、抽取结果日志都属于需要管理的数据资产建议做好访问控制和审计。9.6 从 Ollama 迁移到 vLLM 的时机当单机并发要求提高比如需要同时处理几十个在线抽取请求时Ollama 的并发能力会逐渐成为瓶颈。此时可以迁移到 vLLM。因为代码层使用的是 OpenAI 兼容接口迁移时只需要把base_url指向 vLLM 服务地址业务代码基本不用动。这个架构设计建议在项目一开始就预留。10. 总结与后续学习方向本文围绕“本地模型做 extraction”这条主线讲清楚了几个关键点本地模型适合固定边界的信息抽取任务选型上按任务复杂度和显存上限决定参数量Prompt 设计和 JSON 后处理是决定效果的核心工程环节模型能力不够时靠拆分任务和失败样本回收比盲目换大模型更有效。下一步建议你按这个顺序实践先找一个真实业务字段设计 Schema用本地 7B 模型跑通 20 条测试样本统计准确率针对失败样本迭代 Prompt稳定后接入批量处理脚本并发需求出现时再迁移到 vLLM。如果你想继续深入有三个方向值得关注一是结构化输出约束许多推理框架已经支持 JSON Schema 级别的强约束输出这是提升稳定性的关键二是针对领域数据的轻量微调用几百条标注样本微调底座模型往往比反复调 Prompt 更可靠三是多模态本地模型在 building footprint extraction 这类视觉任务上的应用那是另一条同样值得投入的技术路线。信息抽取这个领域最终拼的不是单次召回率有多高而是整条流水线在真实数据和长期运维中能有多稳。本地模型把主动权交还给了工程师剩下的就看工程做得够不够细了。