健身网站开发方式codeigniter 手机网站开发
2026/5/13 23:24:52 网站建设 项目流程
健身网站开发方式,codeigniter 手机网站开发,怎么让网站快速被收录,织梦网站打开慢从零开始#xff1a;基于Qwen2.5-0.5B的命名实体识别保姆级教程 1. 教程目标与前置准备 本教程旨在带领读者从零开始完成一次完整的命名实体识别#xff08;NER#xff09;任务微调实践#xff0c;使用阿里云开源的大语言模型 Qwen2.5-0.5B-Instruct#xff0c;通过全参…从零开始基于Qwen2.5-0.5B的命名实体识别保姆级教程1. 教程目标与前置准备本教程旨在带领读者从零开始完成一次完整的命名实体识别NER任务微调实践使用阿里云开源的大语言模型Qwen2.5-0.5B-Instruct通过全参数微调方式在中文数据集 CLUENER2020 上实现结构化 JSON 输出的 NER 能力。✅ 学习目标掌握 Qwen2.5 系列模型的基本特性与部署方法完成 CLUENER 数据集的预处理与格式转换构建适用于指令微调的 Dataset 类实现端到端的训练、验证与推理流程使用 TensorBoard 监控训练过程并进行结果分析 前置知识要求Python 编程基础PyTorch 框架基本使用Transformer 模型与 Tokenizer 基础概念Linux 命令行操作能力 环境配置建议GPUNVIDIA 4090D × 4或等效算力显存≥24GB per GPUPython 版本3.9关键依赖库bash torch2.1.0 transformers4.37.0 datasets2.16.0 tensorboard tqdm numpy matplotlib2. 模型与数据集介绍### 2.1 Qwen2.5-0.5B-Instruct 模型特性解析Qwen2.5-0.5B-Instruct是通义千问系列中轻量级但高度优化的指令微调版本具备以下核心优势多语言支持覆盖中文、英文及超过 29 种主流语言长上下文理解最大支持 128K tokens 输入生成最长可达 8K tokens结构化输出能力增强特别优化了 JSON 格式生成表现适合信息抽取类任务高效推理性能0.5B 参数规模适配边缘设备和快速实验场景 ModelScope 下载地址https://modelscope.cn/models/Qwen/Qwen2.5-0.5B-Instruct该模型采用标准的 Causal Language Modeling 架构可通过AutoModelForCausalLM加载并结合AutoTokenizer进行文本编码。### 2.2 CLUENER2020 中文命名实体识别数据集CLUENER 是中文语言理解测评基准CLUE中的细粒度命名实体识别子任务包含 10 类实体标签实体类别示例address北京、上海浦东新区book《三体》、吴三桂演义》company阿里巴巴、浙商银行game英雄联盟、CSOLgovernment国务院、组委会movie加勒比海盗3世界尽头》name李成、叶老桂organization联合国儿童基金会、布鲁京斯研究所position研究部主任、记者scene牛奶海、雪山原始数据为嵌套字典结构包含字符级位置标注。我们将其简化为仅保留实体名称的 JSON 列表形式便于 LLM 直接生成。数据下载与路径规划# 创建项目目录结构 mkdir -p model ner_data_origin ner_data output_ner logs # 下载 CLUENER 数据集需手动访问官网 # https://www.cluebenchmarks.com/introduce.html # 将 train.json 和 dev.json 放入 ner_data_origin/3. 数据预处理与 Token 分布分析### 3.1 数据格式转换脚本由于原始数据包含位置索引[start, end]而本次任务聚焦于实体内容提取而非定位因此需将数据转换为更简洁的形式# trans_data.py import json def trans(file_path, save_path): with open(save_path, a, encodingutf-8) as w: with open(file_path, r, encodingutf-8) as r: for line in r: line json.loads(line) text line[text] label line[label] trans_label {} for key, items in label.items(): items list(items.keys()) # 只保留实体名 if items: trans_label[key] items trans { text: text, label: trans_label } line json.dumps(trans, ensure_asciiFalse) w.write(line \n) w.flush() if __name__ __main__: trans(ner_data_origin/train.json, ner_data/train.json) trans(ner_data_origin/dev.json, ner_data/val.json)运行后生成 -ner_data/train.json训练集10748 条 -ner_data/val.json验证集1343 条### 3.2 Token 长度分布统计为合理设置输入输出长度需分析数据集中文本与标签的 Token 数量分布# token_analysis.py from transformers import AutoTokenizer import json import numpy as np import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] def get_token_distribution(file_path, tokenizer): input_tokens, output_tokens [], [] with open(file_path, r, encodingutf-8) as f: for line in f: data json.loads(line) text data[text] label json.dumps(data[label], ensure_asciiFalse) input_tokens.append(len(tokenizer(text).input_ids)) output_tokens.append(len(tokenizer(label).input_ids)) return input_tokens, output_tokens def plot_token_distribution(): model_path model/Qwen2.5-0.5B-Instruct tokenizer AutoTokenizer.from_pretrained(model_path, trust_remote_codeTrue) inputs, outputs get_token_distribution(ner_data/train.json, tokenizer) print(fInput - Min: {min(inputs)}, Max: {max(inputs)}, Avg: {np.mean(inputs):.1f}) print(fOutput - Min: {min(outputs)}, Max: {max(outputs)}, Avg: {np.mean(outputs):.1f}) plt.figure(figsize(10, 6)) bars plt.bar( [Input Min, Input Max, Input Avg, Output Min, Output Max, Output Avg], [min(inputs), max(inputs), np.mean(inputs), min(outputs), max(outputs), np.mean(outputs)] ) plt.title(CLUENER 训练集 Token 分布) plt.ylabel(Token 数量) for bar in bars: yval bar.get_height() plt.text(bar.get_x() bar.get_width()/2, yval, int(yval), hacenter, vabottom) plt.xticks(rotation15) plt.tight_layout() plt.show() if __name__ __main__: plot_token_distribution()输出示例Input - Min: 12, Max: 50, Avg: 38.2 Output - Min: 15, Max: 69, Avg: 42.7据此设定 -max_source_length 50-max_target_length 140预留空间以应对复杂输出4. 自定义 Dataset 与数据加载器构建### 4.1 NerDataset 类实现创建ner_dataset.py文件封装数据读取与预处理逻辑# ner_dataset.py from torch.utils.data import Dataset import torch import json import numpy as np class NerDataset(Dataset): def __init__(self, data_path, tokenizer, max_source_length, max_target_length) - None: super().__init__() self.tokenizer tokenizer self.max_source_length max_source_length self.max_target_length max_target_length self.max_seq_length self.max_source_length self.max_target_length self.data [] if data_path: with open(data_path, r, encodingutf-8) as f: for line in f: if not line.strip(): continue json_line json.loads(line) text json_line[text] label json_line[label] label json.dumps(label, ensure_asciiFalse) self.data.append({ text: text, label: label }) print(f✅ 数据加载完成共 {len(self.data)} 条) def preprocess(self, text, label): messages [ {role: system, content: 你的任务是做Ner任务提取, 根据用户输入提取出完整的实体信息, 并以JSON格式输出。}, {role: user, content: text} ] prompt self.tokenizer.apply_chat_template( messages, tokenizeFalse, add_generation_promptTrue ) # 编码输入部分prompt instruction self.tokenizer( prompt, add_special_tokensFalse, max_lengthself.max_source_length, paddingmax_length, truncationTrue, return_tensorsNone ) # 编码输出部分label response self.tokenizer( label, add_special_tokensFalse, max_lengthself.max_target_length, paddingmax_length, truncationTrue, return_tensorsNone ) # 拼接 input_ids input_ids instruction[input_ids] response[input_ids] [self.tokenizer.pad_token_id] attention_mask instruction[attention_mask] response[attention_mask] [1] labels [-100] * len(instruction[input_ids]) response[input_ids] [self.tokenizer.pad_token_id] return input_ids, attention_mask, labels def __getitem__(self, index): item_data self.data[index] input_ids, attention_mask, labels self.preprocess(**item_data) return { input_ids: torch.LongTensor(np.array(input_ids)), attention_mask: torch.LongTensor(np.array(attention_mask)), labels: torch.LongTensor(np.array(labels)) } def __len__(self): return len(self.data)⚠️ 注意labels中 prompt 部分用-100掩码确保损失函数只计算生成部分。### 4.2 数据加载器配置在主训练脚本中初始化 DataLoaderfrom torch.utils.data import DataLoader train_params { batch_size: 15, shuffle: True, num_workers: 4, pin_memory: True } val_params { batch_size: 15, shuffle: False, num_workers: 4 } training_set NerDataset(ner_data/train.json, tokenizer, 50, 140) training_loader DataLoader(training_set, **train_params) val_set NerDataset(ner_data/val.json, tokenizer, 50, 140) val_loader DataLoader(val_set, **val_params)5. 全参数微调训练流程### 5.1 主训练脚本实现# train.py import torch from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriter from transformers import AutoModelForCausalLM, AutoTokenizer from ner_dataset import NerDataset from tqdm import tqdm import time, sys def train_model(model, train_loader, val_loader, optimizer, device, num_epochs, model_output_dir, writer): batch_step 0 for epoch in range(num_epochs): time1 time.time() model.train() for index, data in enumerate(tqdm(train_loader, filesys.stdout, descfTrain Epoch {epoch})): input_ids data[input_ids].to(device) attention_mask data[attention_mask].to(device) labels data[labels].to(device) optimizer.zero_grad() outputs model( input_idsinput_ids, attention_maskattention_mask, labelslabels ) loss outputs.loss loss.backward() optimizer.step() writer.add_scalar(Loss/train, loss.item(), batch_step) batch_step 1 if index % 100 0: time2 time.time() print(fStep {index}, Loss: {loss:.4f}, Time per step: {(time2-time1)/(index1):.4f}s) # 验证阶段 model.eval() val_loss validate_model(model, device, val_loader) writer.add_scalar(Loss/val, val_loss, epoch) print(f✅ Epoch {epoch} | Val Loss: {val_loss:.4f}) model.save_pretrained(model_output_dir) def validate_model(model, device, val_loader): running_loss 0.0 with torch.no_grad(): for data in tqdm(val_loader, filesys.stdout, descValidating): input_ids data[input_ids].to(device) attention_mask data[attention_mask].to(device) labels data[labels].to(device) outputs model(input_idsinput_ids, attention_maskattention_mask, labelslabels) running_loss outputs.loss.item() return running_loss / len(val_loader) def main(): model_name model/Qwen2.5-0.5B-Instruct tokenizer AutoTokenizer.from_pretrained(model_name, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained(model_name, trust_remote_codeTrue) device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device) training_set NerDataset(ner_data/train.json, tokenizer, 50, 140) val_set NerDataset(ner_data/val.json, tokenizer, 50, 140) train_loader DataLoader(training_set, batch_size15, shuffleTrue, num_workers4) val_loader DataLoader(val_set, batch_size15, shuffleFalse, num_workers4) optimizer torch.optim.AdamW(model.parameters(), lr1e-4) writer SummaryWriter(logs) train_model( modelmodel, train_loadertrain_loader, val_loaderval_loader, optimizeroptimizer, devicedevice, num_epochs30, model_output_diroutput_ner, writerwriter ) writer.close() if __name__ __main__: main()### 5.2 启动训练与监控# 启动训练 python train.py # 启动 TensorBoard 查看 loss 曲线 tensorboard --logdirlogs --bind_all --port6006浏览器访问http://your-ip:6006即可查看训练动态。6. 模型推理与效果测试### 6.1 测试脚本编写# test.py from transformers import AutoModelForCausalLM, AutoTokenizer import torch def main(): tokenizer AutoTokenizer.from_pretrained(model/Qwen2.5-0.5B-Instruct, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained(output_ner, trust_remote_codeTrue) device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device) test_cases [ 三星WCG2011北京赛区魔兽争霸3最终名次, 新华网孟买3月10日电记者聂云印度国防部10日说印度政府当天批准, 证券时报记者肖渔 ] for case in test_cases: messages [ {role: system, content: 你的任务是做Ner任务提取, 根据用户输入提取出完整的实体信息, 并以JSON格式输出。}, {role: user, content: case} ] prompt tokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue) inputs tokenizer([prompt], return_tensorspt).to(device) gen_kwargs { max_new_tokens: 140, do_sample: False, top_k: 1 } outputs model.generate(**inputs, **gen_kwargs) response tokenizer.decode(outputs[0][inputs[input_ids].shape[-1]:], skip_special_tokensTrue) print(- * 50) print(f 输入: {case}) print(f 输出: {response}) if __name__ __main__: main()### 6.2 预期输出示例-------------------------------------------------- 输入: 三星WCG2011北京赛区魔兽争霸3最终名次 输出: {game: [魔兽争霸3], company: [三星], address: [北京]}7. 总结本文系统地完成了基于Qwen2.5-0.5B-Instruct的命名实体识别微调全流程涵盖数据预处理将 CLUENER 原始数据转为适合 LLM 指令微调的 JSON 格式Token 分析科学设定输入输出长度避免截断或资源浪费Dataset 封装利用apply_chat_template构建符合对话模板的训练样本全参数微调使用 AdamW 优化器进行 30 轮训练配合 TensorBoard 实时监控推理验证成功实现结构化 JSON 输出具备实际应用潜力。✅最佳实践建议 - 若显存受限可改用 LoRA 微调降低资源消耗 - 可扩展支持实体位置输出提升实用性 - 在真实业务数据上继续增量训练提升领域适应性。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

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

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

立即咨询