山东省住房和城乡建设厅网站定额站工业和信息化部教育与考试中心
2026/5/20 20:38:46 网站建设 项目流程
山东省住房和城乡建设厅网站定额站,工业和信息化部教育与考试中心,wordpress 评论添加字段,免费crm系统手机版RaNER模型微调指南#xff1a;自定义实体类型部署实战教程 1. 引言#xff1a;从通用识别到定制化需求 随着自然语言处理技术的普及#xff0c;命名实体识别#xff08;Named Entity Recognition, NER#xff09;已成为信息抽取、知识图谱构建和智能客服等场景的核心能力…RaNER模型微调指南自定义实体类型部署实战教程1. 引言从通用识别到定制化需求随着自然语言处理技术的普及命名实体识别Named Entity Recognition, NER已成为信息抽取、知识图谱构建和智能客服等场景的核心能力。当前主流的中文NER模型如达摩院的RaNER在人名PER、地名LOC、机构名ORG等标准类别上表现出色。然而在实际业务中我们往往需要识别特定领域的实体类型例如“疾病名称”、“药品成分”或“金融产品”。本文将带你完成一次完整的RaNER模型微调与自定义实体类型部署实战涵盖数据准备、模型训练、服务封装与WebUI集成全过程。最终成果是一个支持自定义实体类型的高性能中文NER系统并配备可视化交互界面适用于医疗、金融、法律等多个垂直领域。2. 技术选型与架构设计2.1 为什么选择RaNERRaNERReinforced Named Entity Recognition是阿里巴巴达摩院推出的一种基于强化学习机制优化解码过程的中文命名实体识别模型。其核心优势包括高精度在多个中文NER公开数据集上达到SOTA水平强泛化性预训练于大规模新闻语料具备良好的语义理解能力轻量高效适配CPU推理适合边缘部署和低延迟场景更重要的是RaNER基于ModelScope平台开源提供了完整的训练脚本与API接口极大降低了二次开发门槛。2.2 系统整体架构本项目采用分层架构设计确保模块解耦、易于扩展--------------------- | WebUI前端 | ← Cyberpunk风格界面支持实时高亮 -------------------- | ----------v---------- | REST API服务层 | ← FastAPI驱动提供/json接口 -------------------- | ----------v---------- | RaNER模型推理引擎 | ← 微调后模型加载与预测 -------------------- | ----------v---------- | 模型训练与微调模块 | ← 使用PyTorch Transformers ---------------------所有组件打包为Docker镜像支持一键部署至CSDN星图镜像广场或其他云平台。3. 实战步骤详解从零开始微调RaNER3.1 环境准备首先拉取ModelScope官方RaNER模型并配置依赖环境# 安装必要库 pip install modelscope torch transformers fastapi uvicorn python-multipart jinja2 # 下载基础模型 from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks ner_pipeline pipeline(taskTasks.named_entity_recognition, modeldamo/conv-bert-base-chinese-ner)创建项目目录结构RaNER-Finetune/ ├── data/ # 训练数据 ├── models/ # 存放微调后模型 ├── app.py # API服务主程序 ├── train.py # 微调脚本 ├── templates/index.html # WebUI模板 └── static/ # CSS/JS资源3.2 数据标注与格式转换要支持自定义实体类型如“疾病”、“症状”需准备标注数据。推荐使用Label Studio进行半自动标注。假设我们要识别以下三类新实体 -DIS疾病名称如糖尿病 -SYM症状描述如头晕、乏力 -MED药品名称如阿司匹林原始文本示例“患者因持续高烧和咳嗽就诊初步诊断为肺炎建议服用头孢克洛。”对应标签序列BIO格式患者/O 因/O 持续/O 高烧/B-SYM 和/O 咳嗽/B-SYM 就诊/O /O 初步/O 诊断/O 为/O 肺炎/B-DIS /O 建议/O 服用/O 头孢克洛/B-MED 。/O保存为data/train.txt每行一个token及其标签空行分隔句子。3.3 模型微调实现编写train.py基于HuggingFace Transformers进行微调# train.py import torch from transformers import ConvBertForTokenClassification, ConvBertTokenizerFast, Trainer, TrainingArguments from datasets import Dataset from sklearn.model_selection import train_test_split # 自定义实体标签集 labels [O, B-PER, I-PER, B-LOC, I-LOC, B-ORG, I-ORG, B-DIS, I-DIS, B-SYM, I-SYM, B-MED, I-MED] id2label {i: label for i, label in enumerate(labels)} label2id {label: i for i, label in enumerate(labels)} # 加载 tokenizer tokenizer ConvBertTokenizerFast.from_pretrained(damo/conv-bert-base-chinese-ner) # 构建Dataset def load_data(file_path): with open(file_path, r, encodingutf-8) as f: lines f.readlines() tokens, tags [], [] sentence_tokens, sentence_tags [], [] for line in lines: if line.strip() : if sentence_tokens: tokens.append(sentence_tokens) tags.append(sentence_tags) sentence_tokens, sentence_tags [], [] else: parts line.strip().split() if len(parts) 2: token, tag parts sentence_tokens.append(token) sentence_tags.append(tag) return tokens, tags tokens, tags load_data(data/train.txt) train_tokens, val_tokens, train_tags, val_tags train_test_split(tokens, tags, test_size0.2) # 编码输入 def tokenize_and_align_labels(examples): tokenized_inputs tokenizer(examples[tokens], truncationTrue, is_split_into_wordsTrue) labels [] for i, label in enumerate(examples[tags]): word_ids tokenized_inputs.word_ids(batch_indexi) previous_word_idx None label_ids [] for word_idx in word_ids: if word_idx is None: label_ids.append(-100) elif word_idx ! previous_word_idx: try: label_ids.append(label2id[label[word_idx]]) except KeyError: label_ids.append(label2id[O]) else: label_ids.append(label2id[I- label[word_idx][2:]] if label[word_idx].startswith(B-) else -100) previous_word_idx word_idx labels.append(label_ids) tokenized_inputs[labels] labels return tokenized_inputs # 转换为Dataset对象 train_dataset Dataset.from_dict({tokens: train_tokens, tags: train_tags}) val_dataset Dataset.from_dict({tokens: val_tokens, tags: val_tags}) train_dataset train_dataset.map(tokenize_and_align_labels, batchedTrue) val_dataset val_dataset.map(tokenize_and_align_labels, batchedTrue) # 加载模型 model ConvBertForTokenClassification.from_pretrained( damo/conv-bert-base-chinese-ner, num_labelslen(labels), id2labelid2label, label2idlabel2id ) # 训练参数 training_args TrainingArguments( output_dir./models/rarner-custom, evaluation_strategyepoch, save_strategyepoch, learning_rate5e-5, per_device_train_batch_size16, per_device_eval_batch_size16, num_train_epochs10, weight_decay0.01, logging_dir./logs, load_best_model_at_endTrue, metric_for_best_modeleval_loss, greater_is_betterFalse, save_total_limit2, report_to[] ) # 定义Trainer trainer Trainer( modelmodel, argstraining_args, train_datasettrain_dataset, eval_datasetval_dataset, ) # 开始训练 trainer.train() # 保存模型 trainer.save_model(./models/rarner-custom) tokenizer.save_pretrained(./models/rarner-custom)✅关键点说明 - 使用ConvBertTokenizerFast保持与原模型一致的分词逻辑 - 标签对齐时注意WordPiece拆分问题使用word_ids映射解决 -label2id必须包含原有标签新增标签避免维度不匹配3.4 推理服务封装FastAPI创建app.py暴露REST API并集成WebUI# app.py from fastapi import FastAPI, Request from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates import torch from transformers import ConvBertTokenizerFast, ConvBertForTokenClassification from typing import List app FastAPI() app.mount(/static, StaticFiles(directorystatic), namestatic) templates Jinja2Templates(directorytemplates) # 加载微调后模型 model_path ./models/rarner-custom tokenizer ConvBertTokenizerFast.from_pretrained(model_path) model ConvBertForTokenClassification.from_pretrained(model_path) model.eval() # 实体颜色映射 color_map { PER: red, LOC: cyan, ORG: yellow, DIS: magenta, SYM: orange, MED: lime } app.get(/) async def home(request: Request): return templates.TemplateResponse(index.html, {request: request}) app.post(/ner) async def ner_predict(text: str): inputs tokenizer(text, return_tensorspt, truncationTrue, max_length512) with torch.no_grad(): outputs model(**inputs) predictions torch.argmax(outputs.logits, dim-1).squeeze().tolist() tokens tokenizer.convert_ids_to_tokens(inputs[input_ids].squeeze()) labels [model.config.id2label[p] for p in predictions] result [] for token, label in zip(tokens, labels): if token in [[CLS], [SEP], [PAD]]: continue if token.startswith(##): result[-1][word] token[2:] else: entity_type label[2:] if label.startswith(B-) or label.startswith(I-) else O color color_map.get(entity_type, white) result.append({ word: token, tag: entity_type, color: color }) return {result: result}3.5 WebUI前端实现Cyberpunk风格templates/index.html部分代码!DOCTYPE html html head titleRaNER - 智能实体侦测/title link href/static/style.css relstylesheet /head body classcyberpunk div classcontainer h1 AI 智能实体侦测服务/h1 textarea idinputText placeholder粘贴待分析文本.../textarea button onclickstartDetection() classglow-button 开始侦测/button div idoutput classhighlight-area/div /div script async function startDetection() { const text document.getElementById(inputText).value; const res await fetch(/ner, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ text }) }); const data await res.json(); const output document.getElementById(output); output.innerHTML data.result.map(item span stylecolor:${item.color}; font-weight:bold;${item.word}/span ).join(); } /script /body /html配合CSS实现霓虹灯效、故障动画等Cyberpunk视觉元素。4. 部署与验证4.1 启动服务uvicorn app:app --host 0.0.0.0 --port 7860访问http://localhost:7860即可看到Web界面。4.2 测试案例输入“张伟在北京协和医院被确诊为糖尿病伴有视力模糊等症状医生开具了胰岛素处方。”预期输出 -张伟-北京-协和医院-糖尿病-视力模糊-胰岛素成功识别全部六类实体5. 总结5.1 核心收获通过本次实战我们完成了以下目标掌握RaNER模型微调全流程从数据准备、标签扩展到模型训练实现多类型实体识别在原有PER/LOC/ORG基础上新增DIS/SYM/MED三类构建完整应用系统集成FastAPI服务与Cyberpunk风格WebUI支持一键部署可打包为Docker镜像上传至CSDN星图镜像广场5.2 最佳实践建议小样本冷启动若标注数据少于500条建议使用Prompt Learning增强泛化能力增量训练策略定期用新数据微调模型避免灾难性遗忘性能监控记录P/R/F1指标变化趋势设置自动化报警安全防护对外暴露API时增加速率限制与输入清洗获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询