使用本地大模型 Llama3 进行数据分类标记
背景与需求
在维护一个导航站点时,数据分类是一个核心环节。初期版本由于时间紧迫,数据来源于第三方,仅包含基础信息,缺乏准确的分类标签。目前的筛选功能完全依赖关键字匹配,这种方式存在明显缺陷:
- 准确性低:过于粗暴的关键词匹配容易误判。
- 覆盖不全:部分站点信息未包含特定关键字,但实际分类一致。
- 扩展性差:随着数据量增加,人工维护成本过高。
为了提升数据质量,需要一种自动化、低成本且准确的分发方案。
方案选型
针对约 800 条数据的分类任务,对比了以下三种方案:
- 人工标记:历史数据量大,耗时费力,效率低下。
- 云端 API(如 Kimi/ChatGPT):虽然效果好,但涉及 API 调用成本,且数据隐私需考虑。
- 本地大模型(Llama3 + Ollama):无需 API 费用,数据本地处理,隐私安全,适合测试模型性能。
最终选择第三种方案,利用本地部署的大模型进行批量分类。
环境搭建:Ollama
Ollama 是一个用于运行本地大模型的轻量级工具,支持多种主流模型。安装后,可通过命令行快速启动模型。
安装步骤
- 访问官网下载对应操作系统的安装包。
- 安装完成后,通过终端运行以下命令拉取并启动 Llama3 模型:
ollama run llama3
- 确保服务正常运行,默认监听端口为 11434。
验证运行
可以通过简单的对话测试模型是否响应正常。确认无误后,即可准备调用 API。
API 调用设计
命令行交互不适合批量处理,因此需要使用 Ollama 提供的 HTTP API。主要端点如下:
/api/generate:用于文本生成,适合单轮问答或结构化输出。
/api/chat:用于多轮对话,本场景不需要记忆上下文,故不使用。
请求参数
我们需要构造 JSON 格式的请求体,关键参数包括:
model:指定模型名称,如 llama3。
prompt:输入的分类描述和网站信息。
stream:设置为 false,以便一次性获取完整结果,方便序列化解析。
format:可指定输出格式为 JSON,便于程序处理。
提示词工程与调试
提示词的质量直接决定分类准确率。经过多轮迭代,确定了以下策略:
初始问题
在早期测试中,发现模型倾向于将所有 AI 相关网站归类为 Code&IT 或 AI。这是因为大多数目标网站都包含 "AI Power" 等通用词汇。
优化方案
在 Prompt 中增加否定约束,明确区分通用 AI 技术与垂直领域应用。例如:
所有网站均为 AI 相关网站,不要简单地添加 Code&IT 或 AI 分类,而是结合人工智能的具体应用场景进行分类。除非明显是代码助手、低代码或网站建设工具,否则不要轻易归类为通用 IT 类。
输出格式
要求模型返回标准的 JSON 数组,每个元素包含 url 和 category 字段,便于后续写入数据库或更新文件。
Python 实现示例
以下是基于 requests 库的批量处理脚本示例。该脚本读取数据源,循环调用 API,并将结果保存为新文件。
import requests
import json
import time
OLLAMA_URL = "http://localhost:11434"
MODEL_NAME = "llama3"
PROMPT_TEMPLATE = """
请根据以下网站描述,将其归类到最合适的类别中。
网站描述:{description}
URL: {url}
注意:所有网站都是 AI 相关网站,不要简单地添加 Code&IT 或 AI 分类,而是与人工智能相结合的具体分类。
输出格式必须是 JSON 数组,格式如下:[{"url": "...", "category": "..."}]
"""
def classify_website(url, description):
payload = {
"model": MODEL_NAME,
"prompt": PROMPT_TEMPLATE.format(description=description, url=url),
"stream": False,
"format": "json"
}
try:
response = requests.post(f"{OLLAMA_URL}/api/generate", json=payload, timeout=60)
if response.status_code == 200:
result = response.json()
content = result.get("response", "")
return json.loads(content)
else:
print(f"Error for {url}: {response.text}")
return None
except Exception as e:
print(f"Exception for {url}: {str(e)}")
return None
def batch_process(data_list):
results = []
for item in data_list:
print(f"Processing: {item['url']}")
category_data = classify_website(item['url'], item['description'])
if category_data:
results.extend(category_data)
time.sleep(1)
return results
if __name__ == "__main__":
data_source = [
{"url": "https://example.com", "description": "AI 驱动的图像生成工具"},
{"url": "https://test.com", "description": "自然语言处理聊天机器人"}
]
classified_data = batch_process(data_source)
with open("classified_results.json", "w", encoding="utf-8") as f:
json.dump(classified_data, f, ensure_ascii=False, indent=2)
print("Batch processing completed.")
效果评估
完成批量处理后,通过以下方式验证分类效果:
- 交叉验证:随机抽取分类结果,搜索网站实际内容是否与标签匹配。
- 人工抽查:对置信度较低的数据进行人工复核。
根据实测,在 CPU 占用约 20% 的情况下,处理速度约为每秒 1 条数据,整体准确率约为 80%。对于非极端边缘案例,分类结果具有较高参考价值。
总结
利用本地大模型进行数据分类是一种兼顾成本、隐私与效率的方案。通过合理的提示词工程和稳定的 API 调用,可以显著减少人工标注工作量。未来可进一步优化模型微调,以提升特定领域的分类精度。