恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
DeepSeek合同智能处理:从PDF预处理到法律分词的全链路工程实践
首页
资讯中心
/
DeepSeek合同智能处理:从PDF预处理到法律分词的全链路工程实践
DeepSeek合同智能处理:从PDF预处理到法律分词的全链路工程实践
发布时间:2026/10/9 3:38:07
简介本资源是一份面向法律科技从业者、AI算法工程师及合同智能化产品设计者的深度技术方案聚焦DeepSeek大模型在合同谈判场景中的关键信息抽取与策略生成能力。文档系统阐述了从合同文本预处理、领域词库构建、实体与关系识别到谈判意图识别、条款权重计算及优先级清单生成的全链路技术实现覆盖50个技术章节内容完整、结构严谨支持PDF目录跳转与左侧书签导航便于按需精读。资源为单文件PDF大小13.41MB排版规范文字图表清晰无显示异常。目前已有85人学习下载读者可直接获取涵盖小样本标注、跨领域迁移、注意力机制适配、损失函数设计、早停机制实现等前沿实践细节的477页原创技术沉淀尤其适合需要落地合同AI能力的研发团队参考架构设计与工程调优路径。1. 这不是又一个PDF文档477页DeepSeek合同谈判方案是能跑通的「条款意图→风险量化→优先级清单」全链路工程手册你手头那份刚签回来的并购协议第38条写着“技术改进成果归属甲方”但没说清楚是“单方改进”还是“联合开发”第52条“不可抗力定义”里混进了三处行业惯例术语人工审阅时漏掉了其中一处隐性免责边界——这种细节偏差在真实谈判中不是“可能出错”而是“已经出错”。而这份标着“DeepSeek合同谈判要点智能提取与策略建议方案”的477页PDF不是理论白皮书不是PPT式方案汇报更不是AI幻觉堆砌的Prompt模板集。它是一份按工业级交付标准写的、可拆解、可复现、可嵌入现有法务/商务流程的端到端工程手册从PDF扫描件进、到谈判优先级清单出中间每一步都带参数、带边界、带踩坑记录。它解决的不是“能不能识别‘违约金’这个词”而是“当对手方在付款周期条款里插入‘以甲方验收结果为前提’这个状语时模型如何结合历史仲裁胜率数据、我方履约能力画像、该条款在整份合同中的位置权重动态判定其真实意图是质量保障还是付款拖延并将该条款的谈判优先级从P3实时升至P1”。全文覆盖50个技术章节但核心就三件事关键信息抽取不是NER是跨段落实体关系绑定、对手方条款设置意图识别不是情感分析是基于法律逻辑链的语义推理、谈判优先级清单生成不是简单排序是风险×成本×时间敏感度的加权动态计算。适合两类人一是正在搭建合同智能审阅系统的法务科技团队工程师需要直接抄参数、调模块、避雷区二是想用DeepSeek大模型做垂直领域落地的技术负责人需要看清“通用模型”和“合同场景”之间那道必须亲手填平的鸿沟——比如为什么直接拿DeepSeek-R1做条款分类F1值会掉12.7%而加一层基于双向LSTM的分词边界预测后长句实体召回率提升至93.4%。这不是教你怎么用API这是教你怎么把DeepSeek变成你团队里那个最懂《民法典》第509条、最熟半导体代工合同付款节奏、最清楚上一轮和台积电谈wafer price时哪条保密条款被反复拉锯的“数字谈判专家”。2. 合同文本预处理从PDF扫描件到可训练样本的七步炼金术含OCR纠错与结构化锚点对齐合同智能处理的第一道生死线从来不在模型多大而在输入是否干净。你拿到的PDF可能是律师发来的Word转PDF含完美文字层也可能是对方扫描的纸质合同纯图像模糊噪点还可能是带水印/页眉/表格线的扫描件。这三类输入若用同一套预处理流程后续所有模型都会集体“喝醉”。本方案的预处理不是简单调pdfplumber或PyMuPDF而是构建了四层过滤双通道解析结构化锚点对齐的工业级流水线。下面拆解真实可复现的七步操作每步附代码、参数说明及失效场景。2.1 格式识别与分流先判“生死”再定路径预处理第一步不是解析而是格式诊断。很多团队一上来就用OCR扫全部PDF结果对纯文本PDF造成无谓耗时对扫描件却因未调参导致识别率暴跌。本方案采用轻量级格式探针import fitz # PyMuPDF import cv2 import numpy as np def detect_pdf_type(pdf_path: str) - str: 判定PDF类型text_layer有文字层、scan_image纯图像、mixed混合 返回值text, scan, mixed doc fitz.open(pdf_path) text_layer_count 0 image_count 0 for page in doc: # 检查页面是否有可提取文字 text page.get_text() if len(text.strip()) 50: # 阈值设为50字符避免页眉页脚干扰 text_layer_count 1 # 检查页面是否有图像对象非文字渲染的图 if page.get_images(): image_count 1 if text_layer_count len(doc) and image_count 0: return text elif text_layer_count 0 and image_count 0: return scan else: return mixed # 示例调用 pdf_type detect_pdf_type(contract_v2.pdf) print(fPDF类型: {pdf_type}) # 输出: scan逻辑说明此函数不依赖OCR引擎仅通过PyMuPDF原生API检测文字层存在性与图像对象数量毫秒级完成。参数len(text.strip()) 50是关键——过滤掉页眉页脚等短文本干扰确保“有文字层”指真正合同正文。若返回scan则跳过文本提取直入OCR通道若返回text则走纯文本清洗流mixed则需分页处理。2.2 扫描件OCR不是选引擎而是选“合同专用OCR工作流”对scan型PDF本方案弃用通用OCR API如百度OCR、腾讯OCR因其对合同专有符号如“□”“■”“●”等勾选框、“¥”“€”等货币符号、“第X条”编号识别率不足。而是采用Tesseract 5.3 合同定制化预处理组合# 安装依赖Ubuntu 22.04 sudo apt install tesseract-ocr libtesseract-dev pip install pytesseract opencv-python numpyimport pytesseract import cv2 import numpy as np def ocr_contract_scan(image_path: str) - str: 合同扫描件OCR主流程 步骤1. 灰度化 → 2. 自适应阈值二值化 → 3. 去噪形态学开运算→ 4. 文字区域ROI提取 → 5. Tesseract识别 # 1. 读取并灰度化 img cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) # 2. 自适应阈值比全局阈值更适合合同扫描件的光照不均 binary cv2.adaptiveThreshold( img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2 ) # 3. 形态学去噪开运算先腐蚀后膨胀去除小噪点 kernel np.ones((2,2), np.uint8) denoised cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel) # 4. 文字区域ROI提取基于轮廓面积过滤排除页眉页脚小块 contours, _ cv2.findContours(denoised, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) roi_list [] for cnt in contours: x, y, w, h cv2.boundingRect(cnt) area w * h # 过滤掉太小的区域100像素和过宽的区域页面宽度80% if 100 area (denoised.shape[1] * denoised.shape[0] * 0.8): roi denoised[y:yh, x:xw] roi_list.append(roi) # 5. 对每个ROI调用Tesseract关键指定PSM 6 合同语言包 full_text for i, roi in enumerate(roi_list): # 保存临时ROI图便于调试 cv2.imwrite(f/tmp/roi_{i}.png, roi) # Tesseract PSM 6假设为单栏文本合同最常见布局 # 使用自定义训练的合同语言包tessdata下需有contract.traineddata text pytesseract.image_to_string( roi, langcontract, # 关键非eng是contract.traineddata config--psm 6 --oem 3 -c tessedit_char_whitelist0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ¥€£$%*()_-[]{}|;:,./?\\\\ ) full_text text \n return full_text.strip() # 示例调用需提前训练contract.traineddata # text ocr_contract_scan(/path/to/scan.jpg)参数说明--psm 6单栏文本模式比默认PSM 3更适配合同段落langcontract必须使用合同领域微调的语言包本方案提供已训练好的contract.traineddata含“甲方”“乙方”“不可抗力”“违约责任”等2000合同术语tessedit_char_whitelist显式限定字符集强制过滤掉OCR误识的乱码符号如“”“”这是合同OCR稳定性的命门ROI提取步骤中area (width * height * 0.8)防止将整页作为单个ROI导致Tesseract因文本过长而崩溃或漏字。2.3 文本清洗不是删空格而是重建法律语义骨架OCR或PDF提取后的文本充斥着“第 一 条”“付 款 方 式”等被空格割裂的术语、“ 1 ”“ 2 ”等括号内数字错位、“¥ 1 , 0 0 0 , 0 0 0 . 0 0”等金额空格污染。通用清洗如正则\s替换会破坏法律条款的编号结构。本方案采用规则驱动上下文感知清洗import re def clean_contract_text(raw_text: str) - str: 合同文本深度清洗 重点1. 修复被空格割裂的法律术语 2. 标准化编号格式 3. 金额/日期归一化 text raw_text # 1. 修复被空格割裂的合同术语基于预定义术语库 contract_terms [ 甲方, 乙方, 不可抗力, 违约责任, 争议解决, 付款方式, 履行期限, 知识产权, 保密义务, 单方面终止, 协商一致 ] for term in contract_terms: # 匹配甲 方 → 甲方不 可 抗 力 → 不可抗力 spaced_term r\s.join(list(term)) text re.sub(rf{spaced_term}, term, text) # 2. 标准化编号格式统一为第X条、(X)、X.三种 # 匹配第 一 条 → 第一条 text re.sub(r第\s([零一二三四五六七八九十百千])\s条, r第\1条, text) # 匹配( 1 ) → (1) text re.sub(r\(\s*(\d)\s*\), r(\1), text) # 匹配1 . → 1. text re.sub(r(\d)\s\., r\1., text) # 3. 金额标准化移除金额中的空格和逗号保留小数点 # 匹配¥ 1 , 0 0 0 , 0 0 0 . 0 0 → ¥1000000.00 amount_pattern r([¥$€£])\s*([\d\s,\.]) def normalize_amount(match): currency match.group(1) num_str match.group(2).replace( , ).replace(,, ) # 确保小数点后两位 if . in num_str: parts num_str.split(.) integer_part parts[0] decimal_part parts[1][:2].ljust(2, 0) normalized f{integer_part}.{decimal_part} else: normalized f{num_str}.00 return f{currency}{normalized} text re.sub(amount_pattern, normalize_amount, text) # 4. 日期标准化统一为YYYY-MM-DD # 匹配2023年12月25日 → 2023-12-25 date_pattern r(\d{4})年(\d{1,2})月(\d{1,2})日 text re.sub(date_pattern, r\1-\2-\3, text) return text.strip() # 示例 raw 第 一 条 甲方 应 在 收 到 货 物 后 3 0 日 内 付 款 。 金 额 ¥ 1 , 0 0 0 , 0 0 0 . 0 0 cleaned clean_contract_text(raw) print(cleaned) # 输出: 第一条甲方应在收到货物后30日内付款。金额¥1000000.00逻辑说明此清洗函数不追求“文本变短”而追求“语义不变”。contract_terms列表是本方案内置的477页文档第5章“合同领域专业词汇库”中提炼的高频割裂术语实测可将术语识别准确率从78%提升至94%。金额标准化中parts[1][:2].ljust(2, 0)确保所有金额统一为两位小数避免后续数值特征工程出错。2.4 结构化锚点对齐让“第38条”真正成为可索引的节点清洗后的文本仍是扁平字符串但合同条款有严格层级章→节→条→款→项。本方案在预处理末期注入结构化锚点为后续分词、实体识别提供上下文坐标def add_structural_anchors(cleaned_text: str) - str: 在清洗后文本中插入结构化锚点标记 格式[CHAPTER:1] [SECTION:1.1] [ARTICLE:38] [CLAUSE:38.1] [ITEM:38.1.a] # 正则匹配合同常见编号模式 patterns [ (r(第[零一二三四五六七八九十百千\d]章), r[\1]), (r(第[零一二三四五六七八九十百千\d]节), r[\1]), (r(第\d条), r[\1]), (r(\(\d\)), r[\1]), # (1), (2) (r(\d\.), r[\1]), # 1., 2. (r([a-z]\.), r[\1]), # a., b. ] text cleaned_text for pattern, replacement in patterns: text re.sub(pattern, replacement, text) # 将锚点转换为标准格式如[第38条] → [ARTICLE:38] # 此处简化实际使用中需更精细的映射表 text re.sub(r\[第(\d)条\], r[ARTICLE:\1], text) text re.sub(r\[(\d)\.\], r[CLAUSE:\1], text) text re.sub(r\[([a-z])\.\], r[ITEM:\1], text) return text # 示例 text_with_anchors add_structural_anchors(第38条 甲方有权单方面终止合同。 (1) 终止条件包括...) print(text_with_anchors) # 输出: [ARTICLE:38] 甲方有权单方面终止合同。 [CLAUSE:1] 终止条件包括...作用这些[ARTICLE:38]锚点会被后续的分词器识别为特殊token在BERT/DeepSeek模型的输入中它们成为位置编码的强约束信号确保模型理解“第38条”是一个整体语义单元而非普通名词。这是本方案第39章“长合同文本分段处理”能保持上下文关联的关键前置。2.5 分段与分句不是按句号切而是按法律逻辑切合同句子常以分号、冒号、破折号连接如“付款方式银行转账付款时间货物验收后30日内逾期利息每日0.05%”。按re.split(r[。], text)会错误切分。本方案采用规则模型双驱动分句import jieba def contract_segmentation(text: str) - list: 合同文本分段分句 步骤1. 按章节锚点分段 2. 按法律逻辑分句非标点 # 1. 按结构化锚点分段 segments re.split(r\[ARTICLE:\d\], text) # 移除空段和首段通常是标题 segments [s.strip() for s in segments if s.strip()] # 2. 对每段进行法律逻辑分句 # 定义法律逻辑分隔符比标点更可靠 legal_separators [ r, r, r、, r, # 中文分号、冒号、顿号、逗号在法律文本中常作分句 r\n, r\r\n, # 换行符合同常用换行分条款 r\d\, r\(\d\) # 编号如1、(2) ] sentences [] for seg in segments: # 先按换行符粗分 lines re.split(r\n, seg) for line in lines: if not line.strip(): continue # 再按法律分隔符细分 for sep in legal_separators: if re.search(sep, line): parts re.split(sep, line) for part in parts: if part.strip(): sentences.append(part.strip() sep) break else: # 无分隔符则整行为一句 sentences.append(line.strip()) return sentences # 示例 sentences contract_segmentation([ARTICLE:38] 付款方式银行转账付款时间货物验收后30日内逾期利息每日0.05%) print(sentences) # 输出: [付款方式银行转账, 付款时间货物验收后30日内, 逾期利息每日0.05%]为什么不用BERT分句模型因为法律文本分句逻辑高度固定规则方法准确率超99%且速度是BERT的200倍。本方案第39章明确指出对合同文本规则分句是基线模型分句是兜底——仅当规则无法处理时如极长复合句才调用轻量级BiLSTM分句模型。2.6 标准化存储JSONL格式字段即契约预处理最终输出不是TXT而是JSONL每行一个JSON对象字段设计直指下游任务需求{ doc_id: CONTRACT_2024_001, source_file: merger_agreement_v3.pdf, page_num: 12, segment_type: ARTICLE, segment_id: 38, text: 甲方有权单方面终止合同。, structure_anchors: [[ARTICLE:38], [CLAUSE:38.1]], cleaned_text: 甲方有权单方面终止合同。, ner_labels: [{entity: 甲方, type: PARTY, start: 0, end: 2}, {entity: 合同, type: OBJECT, start: 9, end: 11}], metadata: { contract_type: merger, parties: [ABC Corp, XYZ Ltd], sign_date: 2024-03-15 } }字段价值segment_type/segment_id供后续条款分类模型直接读取无需再做编号识别structure_anchors为注意力机制提供硬约束第9章“基于注意力机制的权重计算”中模型会将[ARTICLE:38]的attention score强制设为最高ner_labels预标注的实体用于半监督训练第13章metadata业务元数据供第42章“历史谈判数据挖掘”做相似性检索。2.7 预处理性能优化批量处理与缓存策略对万级合同库预处理不能单文件串行。本方案采用内存映射Redis缓存进程池import redis import mmap from multiprocessing import Pool # Redis缓存配置避免重复处理同一PDF r redis.Redis(hostlocalhost, port6379, db0) def process_single_pdf(pdf_path: str) - dict: 单PDF处理主函数 # 1. 计算PDF内容MD5快速去重 with open(pdf_path, rb) as f: pdf_md5 hashlib.md5(f.read()).hexdigest() # 2. 检查Redis缓存 cached_result r.get(fpreproc:{pdf_md5}) if cached_result: return json.loads(cached_result) # 3. 执行完整预处理流程调用前述所有函数 pdf_type detect_pdf_type(pdf_path) if pdf_type scan: raw_text ocr_contract_scan(pdf_path) else: raw_text extract_text_from_pdf(pdf_path) # 略 cleaned clean_contract_text(raw_text) anchored add_structural_anchors(cleaned) sentences contract_segmentation(anchored) result { doc_id: fDOC_{pdf_md5[:8]}, sentences: sentences, pdf_type: pdf_type } # 4. 写入Redis缓存TTL 7天 r.setex(fpreproc:{pdf_md5}, 60*60*24*7, json.dumps(result)) return result # 批量处理 if __name__ __main__: pdf_list [a.pdf, b.pdf, c.pdf] with Pool(processes4) as pool: results pool.map(process_single_pdf, pdf_list) # 结果写入JSONL文件 with open(preprocessed_contracts.jsonl, w) as f: for res in results: f.write(json.dumps(res, ensure_asciiFalse) \n)工程价值此脚本在4核服务器上处理1000份平均50页的PDF合同耗时12分钟含OCR较单线程提速3.8倍。r.setex缓存使重复PDF处理时间趋近于0这是第3章“预处理流程自动化与性能优化”的核心实践。3. DeepSeek分词与词性标注为什么直接用jieba会把“不可抗力”切成“不可/抗力”合同文本的分词是整个NLP流水线的“地基”。地基歪了上面所有模型都是危房。你用jieba.cut(不可抗力)得到的是[不可, 抗力]——这在法律语境中是灾难性的“不可抗力”是一个不可分割的法定概念切开后“不可”被识别为副词“抗力”被识别为名词实体识别模型根本找不到这个法律术语。本方案第4章“基于DeepSeek的文本分词与词性标注优化方案”给出的答案不是“换一个更好的开源分词器”而是用双向LSTM建模分词边界 CRF序列标注 合同领域词典强约束的三重保险。下面带你复现这套能真正理解《民法典》第180条的分词系统。3.1 合同分词的致命陷阱通用分词器的“法律失明症”先看问题有多严重。用主流分词器处理典型合同句import jieba import pkuseg # 测试句子 sentence 因不可抗力、政府行为或乙方自身原因导致的延迟不视为违约。 print(jieba结果:, list(jieba.cut(sentence))) # 输出: [因, 不可, 抗力, 、, 政府, 行为, 或, 乙方, 自身, 原因, 导致, 的, 延迟, , 不, 视为, 违约, 。] print(pkuseg结果:, pkuseg.cut(sentence)) # 输出: [因, 不可抗力, 、, 政府, 行为, 或, 乙方, 自身, 原因, 导致, 的, 延迟, , 不, 视为, 违约, 。]现象jieba把“不可抗力”切开pkuseg能保留但pkuseg在“第38条”“1”等编号上仍会失败。根本原因在于通用分词器训练数据来自新闻、百科没有法律语料更不懂“第X条”是法律文本的原子单位。本方案第4.1节称之为“法律失明症”——模型看到“第38条”只当它是“第/38/条”三个字而法律人知道这是指向一个具体权利义务集合的唯一标识符。3.2 DeepSeek基础分词模型的选型为什么选DeepSeek-R1而非Qwen本方案第4.2节明确不微调DeepSeek-V27B而选用DeepSeek-R11.3B作为分词底座。理由很务实维度DeepSeek-R1 (1.3B)DeepSeek-V2 (7B)选择R1原因推理速度120 tokens/sec (A10)35 tokens/sec (A10)合同预处理需高吞吐V2太慢显存占用2.1GB14.8GB边缘设备部署第49章必须低显存领域适配性R1在法律语料上预训练比例更高V2侧重代码与通用文本R1的tokenizer对中文法律术语切分更准实测数据在合同测试集1000句上R1原生分词F182.3%V2为79.1%。小模型在垂直领域有时就是比大模型更懂行。3.3 双向LSTM分词边界预测让模型学会“哪里该切”R1的tokenizer仍会把“第38条”切为[第, 38, 条]。本方案第4.3节提出边界预测层Boundary Prediction Layer在R1的embedding后接一个双向LSTM预测每个字后是否应切分。import torch import torch.nn as nn from transformers import AutoTokenizer, AutoModel class BoundaryPredictor(nn.Module): def __init__(self, model_namedeepseek-ai/deepseek-r1): super().__init__() self.tokenizer AutoTokenizer.from_pretrained(model_name) self.bert AutoModel.from_pretrained(model_name) # 双向LSTM输入维度768R1 hidden size输出2维切/不切 self.lstm nn.LSTM(768, 128, bidirectionalTrue, batch_firstTrue) self.classifier nn.Linear(256, 2) # 256 128*2双向 def forward(self, input_ids, attention_mask): outputs self.bert(input_idsinput_ids, attention_maskattention_mask) sequence_output outputs.last_hidden_state # [batch, seq_len, 768] lstm_out, _ self.lstm(sequence_output) # [batch, seq_len, 256] logits self.classifier(lstm_out) # [batch, seq_len, 2] return logits # 初始化模型 model BoundaryPredictor() tokenizer model.tokenizer # 准备输入注意要对齐字级别非token级别 def char_tokenize(text: str) - list: 将文本按字切分用于边界预测 return list(text) text 第38条甲方有权单方面终止合同。 chars char_tokenize(text) # [第,3,8,条,甲,方,有,权,...] # tokenizer.encode(chars) 会报错需自定义char2id映射此处略 # 实际训练中我们构建char-level vocab将每个汉字映射为id关键设计此LSTM不预测“词是什么”只预测“字后面要不要切”。输出是长度为len(chars)的序列每个位置是[0,1]0不切1切。例如对第38条理想输出是[0,0,0,1]只在“条”后切。这比传统CRF分词更稳定因为不依赖词典纯靠上下文学习。3.4 合同领域词性标注体系为什么“甲方”不是名词而是PARTY通用词性体系如PKU词性集中“甲方”被标为NR专有名词。但在合同中“甲方”是法律主体角色标签其重要性远超普通名词。本方案第4.4节定义了合同专属词性体系Contract POS Tagset共12类标签含义示例为何必须PARTY合同当事人甲方、乙方、丙方、买方、卖方用于后续“甲方付款义务”关系抽取CLAUSE_ID条款编号第38条、(1)、38.1.a作为结构化锚点供优先级计算LEGAL_TERM法律术语不可抗力、违约责任、争议解决触发风险评估模型AMOUNT金额¥1000000.00、USD 50000提取后直接喂给风险量化模型DATE日期2024-03-15、交货后30日内时间敏感度计算依据实现方式在CRF层第4.5节中将PARTY等标签作为强制约束。当模型看到“甲方”二字PARTY标签的发射概率被设为0.99其他标签0.01。这不是让模型“猜”而是告诉它“法律文本里甲方只能是PARTY”。3.5 基于CRF的词性标注序列优化解决“第38条”的标签漂移即使有了专属词性体系模型仍可能把“第38条”标成[DT, CD, NN]定冠词、基数词、名词。本方案第4.5节用条件随机场CRF建模标签转移概率强制CLAUSE_ID序列的合法性from allennlp.modules import ConditionalRandomField # 定义标签索引按Contract POS Tagset顺序 label_vocab {O: 0, PARTY: 1, CLAUSE_ID: 2, LEGAL_TERM: 3, ...} # CRF层在BiLSTM后 crf ConditionalRandomField(num_tagslen(label_vocab)) # 关键定义转移分数矩阵transition matrix # 强制CLAUSE_ID后只能跟O或CLAUSE_ID如“第38条”后可跟“甲方”但“第38条”内部不能断 # 设置transition_score[CLAUSE_ID][O] 10.0极高transition_score[CLAUSE_ID][NR] -10.0禁止 crf.transitions.data[2][0] 10.0 # CLAUSE_ID - O crf.transitions.data[2][2] 5.0 # CLAUSE_ID - CLAUSE_ID允许“第38条(1)” crf.transitions.data[2][1] -10.0 # CLAUSE_ID - PARTY禁止效果加入CRF后“第38条甲方”的标注从[CLAUSE_ID, CLAUSE_ID, CLAUSE_ID, PARTY]错误变为[CLAUSE_ID, CLAUSE_ID, CLAUSE_ID, O]正确因为CRF惩罚了CLAUSE_ID-PARTY的非法转移。CRF不是锦上添花是合同分词的防错保险丝。3.6 分词与词性标注的联合训练一个损失函数两套输出本方案第4.6节摒弃“先分词再标词性”的串行范式采用联合训练Joint Training同一个BiLSTM backbone同时输出分词边界和词性标签。class JointModel(nn.Module): def __init__(self): super().__init__() self.bert AutoModel.from_pretrained(deep p a hrefhttps://download.csdn.net/download/ashyyyy/90382248 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p