AI 训练 JSONL 怎么检查?逐行校验字段并保存错误记录

按演示二分类协议逐行检查训练 JSONL 的字段、非空字符串、整数标签、重复键和编号,将错误原因与原始行号一并保存。

训练 JSONL 不能只检查“文件能被 json.loads 打开”。每行要是一个独立对象,还要检查字段、类型、标签范围、编号重复和重复键。把错误行单独保存,能让数据修正有依据,也能防止少量坏数据悄悄改变训练输入。

下面约定 sample_id、text、label 三个字段,label 只允许整数 0 或 1。这是演示分类协议,不代表所有训练框架的格式;聊天微调、工具调用或其他任务应先采用其真实官方数据协议。

AI 训练 JSONL 怎么检查?逐行校验字段并保存错误记录

明确“合法 JSON”之外的契约

  • 每条记录必须是对象,字段恰好是 sample_id、text、label。
  • 编号和文本为非空字符串,合格记录之间编号唯一。
  • label 为整数 0 或 1;布尔值 true/false 不能因为 Python 类型关系而被当作整数标签。
  • 重复对象键与非标准常量必须拒绝,避免后一个值静默覆盖前一个值。

Python 官方 json 说明指出默认解析会接受重复名称并保留最后一个值,也提供 object_pairs_hook 和 parse_constant 配置。JSONL 则要按行分别调用解析器,不能把整份多对象文件当成一个普通 JSON 对象加载。

逐行校验并保留错误原文

保存为 jsonl_check.py,执行 python jsonl_check.py。示例会覆盖练习目录内三个 demo_ 文件;实际语料请只替换读取路径,不覆盖原文件。

import json
from pathlib import Path

source = Path("demo_records.jsonl")
source.write_text(
    '{"sample_id":"s1","text":"示例文本","label":1}\n'
    '{"sample_id":"s2","text":"另一个示例","label":true}\n'
    '{"sample_id":"s1","text":"重复编号","label":0}\n'
    '{"sample_id":"s3","text":"字段被覆盖","label":0,"label":1}\n'
    'not-json\n', encoding="utf-8"
)

def unique_keys(pairs):
    obj = {}
    for key, value in pairs:
        if key in obj:
            raise ValueError(f"重复键:{key}")
        obj[key] = value
    return obj

def reject_constant(value):
    raise ValueError(f"不允许的 JSON 常量:{value}")

seen = set()
passed = failed = 0
with source.open(encoding="utf-8") as incoming, \
     Path("demo_valid.jsonl").open("w", encoding="utf-8") as good, \
     Path("demo_errors.jsonl").open("w", encoding="utf-8") as bad:
    for line_no, raw in enumerate(incoming, start=1):
        try:
            obj = json.loads(raw, object_pairs_hook=unique_keys,
                             parse_constant=reject_constant)
            if not isinstance(obj, dict) or set(obj) != {"sample_id", "text", "label"}:
                raise ValueError("对象字段不符合协议")
            if not isinstance(obj["sample_id"], str) or not obj["sample_id"].strip():
                raise ValueError("编号必须为非空字符串")
            if not isinstance(obj["text"], str) or not obj["text"].strip():
                raise ValueError("文本必须为非空字符串")
            if type(obj["label"]) is not int or obj["label"] not in {0, 1}:
                raise ValueError("标签必须为整数 0 或 1")
            if obj["sample_id"] in seen:
                raise ValueError("编号与已通过记录重复")
            seen.add(obj["sample_id"])
            good.write(json.dumps(obj, ensure_ascii=False, allow_nan=False) + "\n")
            passed += 1
        except (ValueError, TypeError) as error:
            bad.write(json.dumps({"line_no": line_no, "reason": str(error),
                                  "raw": raw.rstrip("\r\n")}, ensure_ascii=False) + "\n")
            failed += 1

print({"passed": passed, "failed": failed})
assert passed == 1 and failed == 4

核对合格文件和四条错误

固定示例应得到 1 条合格记录和 4 条错误:布尔标签、与合格记录重复的编号、重复 label 键、非 JSON 文本。错误文件应保留原始行号、原因与原文,不能只输出“校验失败”后丢掉位置。

编号重复检查只针对已通过的记录,失败行仍全部保存在错误文件。如果业务要求“任何原始行出现相同编号都要整组复核”,应另建原始编号审计表;本文规则不能替代这个更严格的冲突策略。

从校验结果进入训练准备

  1. 逐条修正 demo_errors 所示类型的问题,再重新生成合格集;保留修正前后与来源映射。
  2. 核对类别分布与文本来源。结构合法不代表标签标对,也不代表数据覆盖真实应用。
  3. 按实体、时间或任务需要划分训练与评测数据,不能因为合格 JSONL 生成了就认为没有数据泄漏。
  4. 合格记录数为零时停止后续训练;有错误时按自己的验收规则处理,不静默把失败部分从报告中省略。

适用范围与规模限制

示例流式读取文本行,但 seen 集合会随合格编号增大。百万级编号可改为数据库唯一约束或外部审计方案,并保持同一判定规则。本文没有训练模型,也没有用这些虚构样本评估业务效果。

实际 JSONL 可能含个人或内部资料,错误文件同样保留原文,应遵守与来源数据一致的访问范围。读者下一步是先用固定五行样本核对错误原因,再改成自己的真实任务协议。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/31987.html

赞 (0)
AI小管家的头像AI小管家
AI 训练 CSV 读错列怎么办?处理 BOM、引号和字段内换行
上一篇 2小时前
RAG 关键词检索怎么做?用 SQLite FTS5 建索引并返回原文出处
下一篇 2小时前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部