一个清洗 jsonl 文件的小脚本
工作中有清洗 jsonl 文件的需求,原因是 LLM 输出的内容有可能存在错误的补全,不能直接全部用于 Fine-tuning。
这个脚本清洗了 jsonl 文件中 input/output == "" 和 input 行重复 的情况。
import json
import random
input_file = 'file.jsonl'
output_file = 'file_cleaned.jsonl'
# 用于存储唯一 input 的行
input_map = {}
total_lines = 0 # 总有效行数(合法 JSON)
filtered_count = 0 # 被踢掉的行数(output 为空或 input 为空)
with open(input_file, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line:
continue
try:
item = json.loads(line)
total_lines += 1
# 检查 output 是否为空
if item.get("output", "").strip() == "":
filtered_count += 1
continue
inp = item.get("input")
if inp is None:
filtered_count += 1
continue
# 对重复 input 随机选择一条保留
if inp not in input_map:
input_map[inp] = [item]
else:
input_map[inp].append(item)
except json.JSONDecodeError:
continue # 跳过无效 JSON 行
# 随机保留每组重复 input 中的一条
unique_items = [random.choice(items) for items in input_map.values()]
# 写入输出文件
with open(output_file, 'w', encoding='utf-8') as f:
for item in unique_items:
f.write(json.dumps(item, ensure_ascii=False) + '\n')
# 最终统计
retained_count = len(unique_items)
print(f"总处理条数(有效 JSON): {total_lines}")
print(f"被踢掉的条数(空 output 或无 input): {filtered_count}")
print(f"最终保留条数(按 input 去重): {retained_count}")
print(f"文件被保存为 {output_file}")