Q: hello | A: hello friend.
Q: hi | A: hi friend.
Q: name | A: i am xslm.
Q: sun | A: the sun is warm.
Q: cat | A: a cat can nap.
Q: dog | A: a dog can run.
Q: red | A: red is a color.
Q: blue | A: blue is a color.
Q: learn | A: i learn from text.
Q: code | A: i can learn code.
Q: moon | A: the moon is in the sky.
Q: rain | A: rain is water.
Q: book | A: i can read a book.
Q: tea | A: tea is warm.
Q: bye | A: bye friend.
prepare.py需要亲手编写的完整源码
读取UTF-8、去重、按完整记录划分训练和验证,避免同样例子同时出现。
from pathlib import Path
lines = [line.strip() for line in Path('data/raw.txt').read_text(encoding='utf-8').splitlines() if line.strip()]
lines = list(dict.fromkeys(lines))
assert len(lines) >= 5, 'write at least five different Q/A lines'
assert all(' | A:' in line and line.startswith('Q:') for line in lines)
train = [line for i, line in enumerate(lines) if i % 5 != 0]
val = [line for i, line in enumerate(lines) if i % 5 == 0]
for name, rows in [('train', train), ('val', val)]:
text = '\n'.join(row.replace(' | A:', '\nA:') for row in rows) + '\n'
Path('data/' + name + '.txt').write_text(text, encoding='utf-8')
print(name, len(rows))
逐行拆解代码
把亲手输入的源码分成小段来读。左边的数字是文件中真实的行号。可以对照里的 line 数字来读。
prepare.py 读取原始资料并去重
from pathlib import Pathlines = [line.strip() for line in Path('data/raw.txt').read_text(encoding='utf-8').splitlines() if line.strip()]lines = list(dict.fromkeys(lines))
用 Path(…).read_text(encoding='utf-8') 把整个文件读成文字,用 splitlines() 按行分开。推导式 [line.strip() for line in … if line.strip()] 去掉首尾空格并丢弃空行。dict.fromkeys(lines) 把行作为放入来去重, 保持插入顺序,所以最先出现的顺序原样保留。用 set 的话,顺序每次运行都可能不同,训练和验证的划分可能会变。
prepare.py 格式检查
assert len(lines) >= 5, 'write at least five different Q/A lines'assert all(' | A:' in line and line.startswith('Q:') for line in lines)
for name, rows in [('train', train), ('val', val)]: text = '\n'.join(row.replace(' | A:', '\nA:') for row in rows) + '\n' Path('data/' + name + '.txt').write_text(text, encoding='utf-8') print(name, len(rows))