
信息抽取的本质是将非结构化数据(文本、文档等)转化为结构化格式(表格、JSON、数据库等)的过程。传统方法依赖规则引擎或有监督学习,需人工设计特征和标注数据,适配性差。而大模型 + Schema的方案通过以下核心逻辑实现高效抽取:

步骤说明:
{
"type": "object",
"properties": {
"title": {"type": "string", "required": true},
"publish_time": {"type": "string", "format": "YYYY-MM-DD HH:mm:ss", "required": true},
"author": {"type": "string", "required": false},
"category": {"type": "string", "enum": ["科技", "财经", "体育", "娱乐"], "required": true},
"keywords": {"type": "array", "items": {"type": "string"}, "required": true},
"abstract": {"type": "string", "required": true}
}
}在基于大模型 + Schema 的结构化信息抽取场景中,Schema 是核心约束(定义 “抽什么、怎么输出”),而 Zero-shot、Few-shot、Chain-of-Thought(CoT)是三种适配不同复杂度场景的抽取范式,本质是通过不同的 Prompt 设计策略,让大模型理解 Schema 并完成抽取。
先定义通用的新闻抽取 Schema(后续所有范式均基于此),明确抽取目标和约束:
{
"type": "object",
"properties": {
"title": {"type": "string", "required": true, "description": "新闻标题(10-100字)"},
"publish_time": {"type": "string", "required": true, "format": "YYYY-MM-DD HH:mm:ss", "description": "发布时间"},
"category": {"type": "string", "required": true, "enum": ["科技", "财经", "体育", "娱乐"], "description": "新闻分类"},
"keywords": {"type": "array", "items": {"type": "string"}, "required": true, "minItems": 2, "maxItems": 5, "description": "核心关键词"},
"abstract": {"type": "string", "required": true, "description": "50-200字核心摘要"}
}
}该 Schema 明确了:字段名称、数据类型、必填性、格式约束(如时间格式)、枚举值(如分类)、数量限制(如关键词 2-5 个),是所有抽取范式的 “目标蓝图”。
仅向大模型提供Schema 约束 + 待抽取文本,不提供任何标注示例,让模型仅通过 Schema 的自然语言描述完成抽取。适用于通用场景、Schema 简单、文本结构规整的场景(如标准化新闻、通用简历)。
利用大模型的 “预训练语义知识”,将 Schema 的结构化要求转化为自然语言指令,让模型直接映射文本内容到 Schema 字段。
2.3.1 Prompt 设计(仅含 Schema + 文本)
def build_zero_shot_prompt(raw_text, schema_desc):
prompt = f"""
### 任务
请严格按照以下Schema要求,抽取文本中的新闻信息,仅输出JSON格式结果(无多余内容)。
### Schema约束
{schema_desc}
### 待抽取文本
{raw_text}
### 输出要求
必须符合以下规则:
1. 字段完全匹配Schema,不得新增/缺失字段;
2. publish_time格式为YYYY-MM-DD HH:mm:ss;
3. category仅可选:科技、财经、体育、娱乐;
4. keywords为2-5个字符串组成的数组;
5. 仅输出JSON,无任何解释性文字。
"""
return prompt
# Schema自然语言描述(零样本核心:清晰传达约束)
schema_desc = """
- title:新闻标题(必填,10-100字)
- publish_time:发布时间(必填,格式YYYY-MM-DD HH:mm:ss)
- category:新闻分类(必填,仅可选:科技、财经、体育、娱乐)
- keywords:核心关键词(必填,2-5个,数组格式)
- abstract:核心摘要(必填,50-200字)
"""
# 待抽取文本
raw_text = """
【标题】2024年中国新能源汽车销量突破3000万辆 【发布时间】2025-01-20 10:30
【正文】中国汽车工业协会发布数据,2024年新能源汽车销量3020万辆,同比增长25.1%,连续8年全球第一,
电池技术升级和政策支持是核心驱动力。
"""2.3.2 模型调用与输出
# Qwen1.5-1.8B-Chat调用(Zero-shot模式)
messages = [
{"role": "system", "content": "你是精准的信息抽取助手,仅输出JSON格式结果。"},
{"role": "user", "content": build_zero_shot_prompt(raw_text, schema_desc)}
]
input_ids = tokenizer.apply_chat_template(messages, return_tensors="pt").to("cpu")
outputs = model.generate(input_ids, max_new_tokens=512, temperature=0.01, do_sample=False)
result = tokenizer.decode(outputs[0][input_ids.shape[1]:], skip_special_tokens=True)
# 输出结果(Zero-shot成功抽取)
{
"title": "2024年中国新能源汽车销量突破3000万辆",
"publish_time": "2025-01-20 10:30:00",
"category": "财经",
"keywords": ["新能源汽车", "销量", "3000万辆", "全球第一"],
"abstract": "2025年1月20日中国汽车工业协会发布数据,2024年新能源汽车销量达3020万辆,同比增长25.1%,连续8年位居全球第一,电池技术升级和政策支持是核心驱动力。"
}在 Zero-shot 的基础上,补充1-5 个 “文本 + 符合 Schema 的结构化输出” 示例,让模型通过示例学习 Schema 的映射规则,提升专业场景的抽取精度。适用于Schema 较复杂、文本场景特殊(如专业领域)、Zero-shot 抽取精度不足的场景(如医疗报告、法律文书、行业新闻)。
大模型的 “少样本学习能力”+ Schema 约束,通过示例具象化 “文本内容如何对应 Schema 字段”,降低模型对抽象 Schema 的理解成本,提升抽取准确性。
3.3.1 Prompt 设计(Schema+3 个示例 + 待抽取文本)
def build_few_shot_prompt(raw_text, schema_desc):
# 示例1:科技新闻(锚定Schema字段映射)
example1_text = """
【标题】ChatGLM-6B-int4版本发布 支持CPU本地运行 【发布时间】2024-03-15 09:00
【正文】智谱AI推出ChatGLM-6B的4位量化版本,普通CPU即可运行,内存占用仅8GB,适配信息抽取场景。
"""
example1_output = """
{
"title": "ChatGLM-6B-int4版本发布 支持CPU本地运行",
"publish_time": "2024-03-15 09:00:00",
"category": "科技",
"keywords": ["ChatGLM-6B", "int4量化", "CPU运行", "信息抽取"],
"abstract": "2024年3月15日智谱AI发布ChatGLM-6B-int4版本,普通CPU即可运行,内存占用仅8GB,适配信息抽取场景。"
}
"""
# 示例2:体育新闻(锚定枚举值约束)
example2_text = """
【标题】国足世预赛3-0击败越南 【发布时间】2024-06-20 20:00
【正文】2024年世预赛亚洲区比赛中,国足3-0战胜越南队,斩获小组赛首胜,进攻端效率显著提升。
"""
example2_output = """
{
"title": "国足世预赛3-0击败越南",
"publish_time": "2024-06-20 20:00:00",
"category": "体育",
"keywords": ["国足", "世预赛", "3-0", "越南"],
"abstract": "2024年6月20日世预赛亚洲区比赛中,国足3-0击败越南队,斩获小组赛首胜,进攻端效率显著提升。"
}
"""
# 示例3:娱乐新闻(锚定关键词数量约束)
example3_text = """
【标题】周杰伦新专辑《最伟大的作品》销量破千万 【发布时间】2024-07-01 12:00
【正文】周杰伦2024年新专辑上线7天销量突破1000万张,主打歌全网播放量超5亿次。
"""
example3_output = """
{
"title": "周杰伦新专辑《最伟大的作品》销量破千万",
"publish_time": "2024-07-01 12:00:00",
"category": "娱乐",
"keywords": ["周杰伦", "新专辑", "销量破千万"],
"abstract": "2024年7月1日周杰伦新专辑《最伟大的作品》上线7天销量突破1000万张,主打歌全网播放量超5亿次。"
}
"""
prompt = f"""
### 任务
严格按照以下Schema要求,抽取文本中的新闻信息,仅输出JSON格式结果(无多余内容)。
### Schema约束
{schema_desc}
### 参考示例(共3个)
示例1输入:{example1_text}
示例1输出:{example1_output}
示例2输入:{example2_text}
示例2输出:{example2_output}
示例3输入:{example3_text}
示例3输出:{example3_output}
### 待抽取文本
{raw_text}
### 输出要求
完全遵循Schema约束,输出格式与示例一致,仅输出JSON!
"""
return prompt
# 待抽取文本(专业财经场景,Zero-shot易出错)
raw_text = """
【标题】2024年A股上市公司净利润同比增长8.2% 【发布时间】2025-01-30 15:30
【正文】证监会发布2024年A股年报数据,全部上市公司净利润合计5.6万亿元,同比增长8.2%,
其中金融行业贡献35%,制造业增长10.5%,消费行业复苏明显。
"""3.3.2 模型调用与输出
# Qwen1.5-1.8B-Chat调用(Few-shot模式)
messages = [
{"role": "system", "content": "你是精准的信息抽取助手,仅输出JSON格式结果。"},
{"role": "user", "content": build_few_shot_prompt(raw_text, schema_desc)}
]
input_ids = tokenizer.apply_chat_template(messages, return_tensors="pt").to("cpu")
outputs = model.generate(input_ids, max_new_tokens=512, temperature=0.01, do_sample=False)
result = tokenizer.decode(outputs[0][input_ids.shape[1]:], skip_special_tokens=True)
# 输出结果(Few-shot精准抽取专业字段)
{
"title": "2024年A股上市公司净利润同比增长8.2%",
"publish_time": "2025-01-30 15:30:00",
"category": "财经",
"keywords": ["A股", "上市公司", "净利润", "同比增长8.2%", "金融行业"],
"abstract": "2025年1月30日证监会发布2024年A股年报数据,全部上市公司净利润合计5.6万亿元,同比增长8.2%,金融行业贡献35%,制造业增长10.5%,消费行业复苏明显。"
}将复杂的 Schema 抽取任务拆解为多步逻辑推理,让模型 “分步思考”:先识别文本中的核心信息→再匹配 Schema 字段→最后校验约束,适用于Schema 极复杂(嵌套结构、多维度关联)、文本信息零散、抽取逻辑复杂的场景(如企业年报、多实体关联的新闻)。
4.3.1 Schema 升级(复杂嵌套结构) 先扩展为复杂嵌套 Schema(CoT 的核心适用场景):
{
"type": "object",
"properties": {
"title": {"type": "string", "required": true},
"publish_time": {"type": "string", "required": true, "format": "YYYY-MM-DD HH:mm:ss"},
"category": {"type": "string", "required": true, "enum": ["科技", "财经", "体育", "娱乐"]},
"core_data": { // 嵌套结构(CoT重点处理)
"type": "object",
"properties": {
"total_value": {"type": "string", "required": true, "description": "核心数值(带单位)"},
"growth_rate": {"type": "string", "required": true, "description": "同比增长率"},
"contribution_sectors": {"type": "array", "items": {"type": "string"}, "required": true}
}
},
"keywords": {"type": "array", "items": {"type": "string"}, "required": true, "minItems": 2},
"abstract": {"type": "string", "required": true}
}
}4.3.2 Prompt 设计(CoT+Schema + 分步推理)
def build_cot_prompt(raw_text, schema_desc):
prompt = f"""
### 任务
请按照以下步骤抽取文本信息,最终输出符合Schema的JSON结果(无多余内容)。
### Schema约束
{schema_desc}
### 推理步骤(必须严格执行)
步骤1:从文本中提取新闻标题、发布时间、分类(仅选:科技/财经/体育/娱乐);
步骤2:从文本中提取核心数据:总数值(带单位)、同比增长率、贡献行业列表;
步骤3:从文本中提取2-5个核心关键词;
步骤4:基于以上信息,撰写50-200字的摘要;
步骤5:将所有信息整合为符合Schema的JSON格式,检查约束(格式、数量、枚举值)。
### 待抽取文本
{raw_text}
### 输出要求
先输出每一步的推理过程,最后输出最终JSON结果(仅JSON)!
"""
return prompt
# 待抽取文本(信息零散+嵌套Schema,普通范式易出错)
raw_text = """
【标题】2024年中国数字经济规模突破60万亿元 【发布时间】2025-02-10 11:00
【正文】工信部2025年2月发布《2024数字经济发展报告》:
1. 全年数字经济总规模60.5万亿元,同比增长10.3%;
2. 产业数字化贡献75%(制造业占40%、服务业占35%);
3. 数字产业化增长8.7%,人工智能、云计算是核心驱动力。
"""4.3.3 模型调用与输出
# Qwen1.5-1.8B-Chat调用(CoT模式)
messages = [
{"role": "system", "content": "你是具备逻辑推理能力的信息抽取助手,严格按步骤推理。"},
{"role": "user", "content": build_cot_prompt(raw_text, schema_desc)}
]
input_ids = tokenizer.apply_chat_template(messages, return_tensors="pt").to("cpu")
outputs = model.generate(input_ids, max_new_tokens=1024, temperature=0.01, do_sample=False)
result = tokenizer.decode(outputs[0][input_ids.shape[1]:], skip_special_tokens=True)
# 模型输出(先推理,后输出JSON)
"""
步骤1:提取基础信息
- 标题:2024年中国数字经济规模突破60万亿元
- 发布时间:2025-02-10 11:00:00
- 分类:科技
步骤2:提取核心数据
- 总数值:60.5万亿元
- 同比增长率:10.3%
- 贡献行业:制造业、服务业、人工智能、云计算
步骤3:提取关键词
- 关键词:数字经济、60.5万亿元、同比增长10.3%、制造业、人工智能
步骤4:撰写摘要
- 摘要:2025年2月10日工信部发布《2024数字经济发展报告》,全年数字经济总规模达60.5万亿元,同比增长10.3%,产业数字化贡献75%(制造业占40%、服务业占35%),数字产业化增长8.7%,人工智能、云计算是核心驱动力。
步骤5:整合JSON
{
"title": "2024年中国数字经济规模突破60万亿元",
"publish_time": "2025-02-10 11:00:00",
"category": "科技",
"core_data": {
"total_value": "60.5万亿元",
"growth_rate": "10.3%",
"contribution_sectors": ["制造业", "服务业", "人工智能", "云计算"]
},
"keywords": ["数字经济", "60.5万亿元", "同比增长10.3%", "制造业", "人工智能"],
"abstract": "2025年2月10日工信部发布《2024数字经济发展报告》,全年数字经济总规模达60.5万亿元,同比增长10.3%,产业数字化贡献75%(制造业占40%、服务业占35%),数字产业化增长8.7%,人工智能、云计算是核心驱动力。"
}
"""
# 提取最终JSON结果(过滤推理步骤)
json_start = result.find("{")
json_end = result.rfind("}") + 1
final_result = json.loads(result[json_start:json_end])
简单说明:
这个流程图描述了根据Schema复杂度和文本特性选择最合适的抽取策略的过程:
通过简单的Schema提取文本中的公司名称
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
from modelscope.hub.snapshot_download import snapshot_download
# 加载模型
model_id = "qwen/Qwen1.5-1.8B-Chat"
cache_dir = "D:\\modelscope\\hub"
local_model_path = snapshot_download(model_id, cache_dir=cache_dir)
tokenizer = AutoTokenizer.from_pretrained(local_model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
local_model_path,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
model.eval()
print("模型加载完成")
def simple_extract(text, schema):
"""最简单的抽取函数"""
prompt = f"""
请从文本中提取信息,输出JSON格式:
文本:{text}
Schema要求:{schema}
只输出JSON,不要其他内容。"""
messages = [{"role": "user", "content": prompt}]
inputs = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
input_ids = tokenizer(inputs, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(
**input_ids,
max_new_tokens=200,
temperature=0.1
)
response = tokenizer.decode(outputs[0][input_ids.input_ids.shape[1]:],
skip_special_tokens=True)
return response
# 测试1:提取公司名称
text1 = "苹果公司是美国的一家科技公司。"
schema1 = '{"company_name": "公司名称"}'
result1 = simple_extract(text1, schema1)
print("示例1 - 提取公司名称")
print(f"输入: {text1}")
print(f"输出: {result1}\n")输出结果:
示例1 - 提取公司名称 输入: 苹果公司是美国的一家科技公司。 输出: { "company_name": "苹果公司" }
提取文本中的公司名称、成立年份、总部地点、首席执行官。
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
from modelscope.hub.snapshot_download import snapshot_download
# 加载模型
model_id = "qwen/Qwen1.5-1.8B-Chat"
cache_dir = "D:\\modelscope\\hub"
local_model_path = snapshot_download(model_id, cache_dir=cache_dir)
tokenizer = AutoTokenizer.from_pretrained(local_model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
local_model_path,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
model.eval()
print("模型加载完成")
def extract_multiple_fields():
"""多字段抽取示例"""
text = "特斯拉公司成立于2003年,总部在德克萨斯州奥斯汀,CEO是埃隆·马斯克。"
schema = {
"company_name": "公司名称",
"founded_year": "成立年份",
"headquarters": "总部地点",
"ceo": "首席执行官"
}
prompt = f"""请从文本中提取信息:
文本:{text}
请按照以下字段提取:
{json.dumps(schema, ensure_ascii=False, indent=2)}
输出JSON格式:"""
messages = [{"role": "user", "content": prompt}]
inputs = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
input_ids = tokenizer(inputs, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(
**input_ids,
max_new_tokens=300,
temperature=0.1
)
response = tokenizer.decode(outputs[0][input_ids.input_ids.shape[1]:],
skip_special_tokens=True)
return response
import json
result2 = extract_multiple_fields()
print("示例2 - 多字段抽取")
print(f"输入: 特斯拉公司成立于2003年,总部在德克萨斯州奥斯汀,CEO是埃隆·马斯克。")
print(f"输出: {result2}\n")输出结果:
示例2 - 多字段抽取 输入: 特斯拉公司成立于2003年,总部在德克萨斯州奥斯汀,CEO是埃隆·马斯克。 输出: { "company_name": "特斯拉公司", "founded_year": "2003", "headquarters": "德克萨斯州奥斯汀", "ceo": "埃隆·马斯克" }
从文本中指定要求的经营产品列表,返回一个数据集合。
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
from modelscope.hub.snapshot_download import snapshot_download
# 加载模型
model_id = "qwen/Qwen1.5-1.8B-Chat"
cache_dir = "D:\\modelscope\\hub"
local_model_path = snapshot_download(model_id, cache_dir=cache_dir)
tokenizer = AutoTokenizer.from_pretrained(local_model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
local_model_path,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
model.eval()
print("模型加载完成")
def extract_array():
"""数组类型抽取"""
text = "华为的主要产品有手机、笔记本电脑、平板电脑、智能手表和耳机。"
schema = {
"company": "公司名称",
"products": ["产品列表", "字符串数组"]
}
prompt = f"""从文本中提取结构化信息:
文本:{text}
提取以下字段:
1. company: 公司名称
2. products: 产品列表,用数组表示
输出JSON格式:"""
messages = [{"role": "user", "content": prompt}]
inputs = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
input_ids = tokenizer(inputs, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(**input_ids, max_new_tokens=300, temperature=0.1)
response = tokenizer.decode(outputs[0][input_ids.input_ids.shape[1]:],
skip_special_tokens=True)
return response
result3 = extract_array()
print("示例3 - 数组类型抽取")
print(f"输入: 华为的主要产品有手机、笔记本电脑、平板电脑、智能手表和耳机。")
print(f"输出: {result3}\n")输出结果:
示例3 - 数组类型抽取 输入: 华为的主要产品有手机、笔记本电脑、平板电脑、智能手表和耳机。 输出: { "company": "华为", "products": ["手机", "笔记本电脑", "平板电脑", "智能手表", "耳机"] }
从一段示例内容中提取指定的嵌套内容信息。
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
from modelscope.hub.snapshot_download import snapshot_download
# 加载模型
model_id = "qwen/Qwen1.5-1.8B-Chat"
cache_dir = "D:\\modelscope\\hub"
local_model_path = snapshot_download(model_id, cache_dir=cache_dir)
tokenizer = AutoTokenizer.from_pretrained(local_model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
local_model_path,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
model.eval()
print("模型加载完成")
def extract_nested():
"""嵌套对象抽取"""
text = "小米14手机,售价3999元,搭载骁龙8Gen3处理器,12GB内存,256GB存储。"
schema = """
{
"product_name": "产品名称",
"price": "价格",
"specs": {
"processor": "处理器",
"memory": "内存",
"storage": "存储"
}
}
"""
prompt = f"""请从产品描述中提取信息:
文本:{text}
严格按照以下JSON Schema格式输出:
{schema}
只输出JSON,不要其他内容。"""
messages = [{"role": "user", "content": prompt}]
inputs = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
input_ids = tokenizer(inputs, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(**input_ids, max_new_tokens=400, temperature=0.1)
response = tokenizer.decode(outputs[0][input_ids.input_ids.shape[1]:],
skip_special_tokens=True)
return response
result4 = extract_nested()
print("示例4 - 嵌套对象抽取")
print(f"输入: 小米14手机,售价3999元,搭载骁龙8Gen3处理器,12GB内存,256GB存储。")
print(f"输出: {result4}\n")输出结果:
示例4 - 嵌套对象抽取 输入: 小米14手机,售价3999元,搭载骁龙8Gen3处理器,12GB内存,256GB存储。 输出: { "product_name": "小米14手机", "price": 3999, "specs": { "processor": "骁龙8Gen3", "memory": "12GB", "storage": "256GB" } }
从示例内容中提取三元组内容信息。
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
from modelscope.hub.snapshot_download import snapshot_download
# 加载模型
model_id = "qwen/Qwen1.5-1.8B-Chat"
cache_dir = "D:\\modelscope\\hub"
local_model_path = snapshot_download(model_id, cache_dir=cache_dir)
tokenizer = AutoTokenizer.from_pretrained(local_model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
local_model_path,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
model.eval()
print("模型加载完成")
def extract_relations():
"""关系抽取示例"""
text = "任正非创立了华为,华为总部在深圳,胡厚崑是华为的轮值董事长。"
schema = """
{
"relations": [
{
"subject": "主体",
"predicate": "关系类型",
"object": "客体"
}
]
}
"""
prompt = f"""从文本中抽取实体关系:
文本:{text}
抽取(主体, 关系, 客体)三元组。关系类型包括:创立、位于、担任。
输出格式:
{schema}
只输出JSON:"""
messages = [{"role": "user", "content": prompt}]
inputs = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
input_ids = tokenizer(inputs, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(**input_ids, max_new_tokens=500, temperature=0.1)
response = tokenizer.decode(outputs[0][input_ids.input_ids.shape[1]:],
skip_special_tokens=True)
return response
result5 = extract_relations()
print("示例5 - 关系抽取")
print(f"输入: 任正非创立了华为,华为总部在深圳,胡厚崑是华为的轮值董事长。")
print(f"输出: {result5}\n")输出结果:
示例5 - 关系抽取 输入: 任正非创立了华为,华为总部在深圳,胡厚崑是华为的轮值董事长。 输出: { "relations": [ {"subject": "任正非", "predicate": "创立", "object": "华为"}, {"subject": "华为", "predicate": "位于", "object": "深圳"}, {"subject": "胡厚崑", "predicate": "担任", "object": "华为的轮值董事长"} ] }
从文本内容中提取复杂对象数组。
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
from modelscope.hub.snapshot_download import snapshot_download
# 加载模型
model_id = "qwen/Qwen1.5-1.8B-Chat"
cache_dir = "D:\\modelscope\\hub"
local_model_path = snapshot_download(model_id, cache_dir=cache_dir)
tokenizer = AutoTokenizer.from_pretrained(local_model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
local_model_path,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
model.eval()
print("模型加载完成")
def extract_complex_array():
"""复杂对象数组抽取"""
text = """
公司员工信息:
1. 张三,30岁,软件工程师,月薪25000元
2. 李四,28岁,产品经理,月薪30000元
3. 王五,35岁,技术总监,月薪50000元
"""
schema = """
{
"employees": [
{
"name": "姓名",
"age": "年龄",
"position": "职位",
"salary": "月薪"
}
]
}
"""
prompt = f"""从文本中提取员工信息:
文本:{text}
提取所有员工信息,填充到数组中。
输出格式:
{schema}
只输出JSON:"""
messages = [{"role": "user", "content": prompt}]
inputs = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
input_ids = tokenizer(inputs, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(**input_ids, max_new_tokens=600, temperature=0.1)
response = tokenizer.decode(outputs[0][input_ids.input_ids.shape[1]:],
skip_special_tokens=True)
return response
result6 = extract_complex_array()
print("示例6 - 复杂对象数组")
print(f"输入: 公司员工信息...")
print(f"输出: {result6}\n")输出结果:
示例6 - 复杂对象数组 输入: 公司员工信息... 输出: { "employees": [ {"name": "张三", "age": 30, "position": "软件工程师", "salary": 25000}, {"name": "李四", "age": 28, "position": "产品经理", "salary": 30000}, {"name": "王五", "age": 35, "position": "技术总监", "salary": 50000} ] }
封装统一的公共执行方法,单组指定每类需要提取的信息。
#!/usr/bin/env python3
"""
Schema信息抽取 - 完整可执行脚本
"""
import json
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
from modelscope import snapshot_download
class QwenSchemaExtractor:
def __init__(self):
print("初始化模型...")
model_id = "qwen/Qwen1.5-1.8B-Chat"
cache_dir = "D:\\modelscope\\hub"
print("正在下载/校验模型缓存...")
local_model_path = snapshot_download(model_id, cache_dir=cache_dir)
self.tokenizer = AutoTokenizer.from_pretrained(
local_model_path,
trust_remote_code=True
)
self.model = AutoModelForCausalLM.from_pretrained(
local_model_path,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
self.model.eval()
print("模型加载完成")
def extract(self, text, schema_desc):
"""执行抽取"""
prompt = f"""请从文本中提取信息,输出JSON格式。
文本:{text}
提取要求:{schema_desc}
只输出JSON,不要其他内容。"""
messages = [{"role": "user", "content": prompt}]
inputs = self.tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
input_ids = self.tokenizer(inputs, return_tensors="pt").to(self.model.device)
with torch.no_grad():
outputs = self.model.generate(
**input_ids,
max_new_tokens=300,
temperature=0.1,
do_sample=True
)
response = self.tokenizer.decode(
outputs[0][input_ids.input_ids.shape[1]:],
skip_special_tokens=True
)
return response
# 创建抽取器
extractor = QwenSchemaExtractor()
# 演示1:产品信息
print("\n" + "="*50)
print("演示1:产品信息抽取")
print("="*50)
product_text = "华为Mate 60 Pro手机,售价6999元,搭载麒麟9000S芯片,支持卫星通信。"
product_schema = "提取:产品名称、价格、芯片型号、特殊功能"
result = extractor.extract(product_text, product_schema)
print(f"产品:{product_text}")
print(f"输出:{result}")
# 演示2:公司信息
print("\n" + "="*50)
print("演示2:公司信息抽取")
print("="*50)
company_text = "腾讯控股有限公司成立于1998年,总部在深圳,主要业务是社交和游戏。"
company_schema = "提取:公司名称、成立年份、总部地点、主要业务"
result = extractor.extract(company_text, company_schema)
print(f"公司:{company_text}")
print(f"输出:{result}")输出结果:
================================================== 演示1:产品信息抽取 ================================================== 产品:华为Mate 60 Pro手机,售价6999元,搭载麒麟9000S芯片,支持卫星通信。 输出:{ "product_name": "华为Mate 60 Pro", "price": "6999元", "chip_model": "麒麟9000S", "special_features": [ "卫星通信" ] } ================================================== 演示2:公司信息抽取 ================================================== 公司:腾讯控股有限公司成立于1998年,总部在深圳,主要业务是社交和游戏。 输出:{ "公司名称": "腾讯控股有限公司", "成立年份": "1998年", "总部地点": "深圳", "主要业务": "社交和游戏" }
基于大模型 + Schema 的信息抽取中,Zero-shot、Few-shot、CoT 三种范式核心差异在于对 Schema 的适配策略与场景匹配度。
实际落地需按 Schema 复杂度择取:通用简单场景优先 Zero-shot,专业场景升级 Few-shot,仅 Schema 嵌套或文本零散时用 CoT,最终均需 Pydantic 校验 Schema 约束。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。