从原始文件到可复跑的资料助手
最后一章把前七章拼成一个能独立运行的项目,而不是再加一段与正文无关的演示。下载目录包含rag_lab源码、原创原件、冻结模型与训练记录、查询和扰动报告、测试及依赖说明。学生不需要从另一门课复制文件,也不需要远程API密钥、GPU或预训练权重。读者最低条件是Python基础、向量和导数;课程导入PyTorch自动微分与卷积算子,并以解析小例、有限差分与真实测试核对使用方式。
环境要求Python至少三点十一:NumPy二点三点五本身要求这个范围,不能因为源码大多简单就写成支持Python三点九。requirements固定torch二点六、NumPy二点三点五和Pillow十二点三。作者实际环境Python三点十二、CPU单线程。依赖安装需要常规软件源网络,运行与验证数据则都在下载包内,没有运行中外发原件的路径。各平台浮点差异仍可能影响极近并列,不能宣传任意机器逐字节相同。
文件职责清晰但围绕同一个信息流。data负责原创PNG和Markdown生成、真实像素读取、固定特征、中文词法单位及文档位置提取;encoder负责真实两分支网络、双向损失、训练与冻结加载;retrieval负责建索引、BM25、RRF、覆盖重排、上下文选择、原件验证和支持回答;run把这些连接为单次查询与固定题评价;stress从原图生成真实扰动并比较两个分支。测试直接调用这些生产函数,不另外编一条只为通过的管线。
算例一:一条真实查询的全部中间状态
在项目根目录运行文字查询“借阅台 开放时间”。程序加载冻结模型并从实际文件建索引,词法找到借阅台对应原行,学习分支对没有域内几何词的查询不给图像候选,融合仍能保留文档。重排确认主题和字段逐字匹配,字符预算保留完整行,回答前检查原件散列和区间,最后输出原值与引用。若结果只是打印一句预写时间,却没有经过这些函数,就不满足本项目合同。
from pathlib import Path
from rag_lab.encoder import load_checkpoint
from rag_lab.retrieval import build_index
from rag_lab.run import query_once
root=Path('data/inputs'); checkpoint=Path('evidence/encoder/encoder.pt')
model,vocab,_=load_checkpoint(checkpoint)
index=build_index(root,checkpoint)
r=query_once('借阅台 开放时间',index,model,vocab,root)
assert r['result']['status']=='answered'
assert r['result']['answer']=='周二至周五十四点到十七点。'
assert r['result']['citations'][0]['source']=='documents/borrowing.md'
print(r['context_ids'],r['result'])接着把查询换成“红色 小 圆形”,同一个索引还包含真实像素向量,模型词袋可处理三个属性,最终支持检查逐项验证像素测量。把查询再加“材质”应拒答;把问题换成“测试台 开放时间”应保留冲突。它们共享同一入口query_once,区别来自资料与合同,不是为每题手写不同答案。输出的candidate_scores、context_ids与citations共同形成可检查轨迹。
命令行直接使用Python模块入口,当前工作目录必须是项目根目录。单次查询用python -m rag_lab.run --query,三十九题用同一模块不带query并指定新的输出目录。重做评价不必重训,使用已经提供的encoder.pt即可。为了保存作者冻结证据,README把学生新报告写入runs/evaluation,不覆盖evidence。如果学生确实希望重新训练,另选runs/encoder输出,记录新检查点散列并用它贯穿后续所有评价。
python -m rag_lab.run --query '红色 小 圆形'
python -m rag_lab.run --output-dir runs/evaluation
python -m rag_lab.stress --output-dir runs/stress
python -m tests.run_tests算例二:独立训练与冻结复现的区别
冻结复现读取作者同一权重,重新提取文件、算查询和扰动,检查结果与记录一致;它验证推理链与证据完整性。重新训练则从指定随机种子开始更新二十对图文,得到新权重,即便相同配置也应另记环境与散列。检查点torch保存容器的字节身份可能受输出文件名等序列化细节影响,不能把仅散列不同比较成模型数值必不同;要区分文件身份与参数逐张量比较。
作者训练二百二十步,测试套件为了快速集成验证另在临时目录训练八十步。后者检查训练损失下降、二十训练ID排除四留出ID、冻结推理不改权重、固定词法流程可通过,而不是用八十步成绩替换二百二十步论文式报告。测试创建原件与临时模型,结束后清理临时目录,学生不会因为跑测试而覆盖作者主检查点。测试本身的结果报告与时间写入evidence/test-results,若要保持原包完全只读,应在解压副本上运行。
参数总数也可独立逐层核对。第一卷积为,第二为;图像线性层为。域内词有四颜色、三形状和两大小,共九个,再加未知项共十维,因此文字首层为,末层为。五项相加得到。词表不能只数九个已知单位而漏掉未知项,也不能把查询里临时出现的未知词自动扩张进冻结词表;否则网络参数形状和检查点都不再匹配。这个逐层算例独立核对了程序的参数统计。
参数梯度测试先固定小批与种子,用双精度网络计算损失并反向传播,逐个参数张量要求梯度存在、有限、总绝对值正。再选文本输出层一个权重,分别加减很小扰动,用两次损失之差除两倍步长,和解析自动微分值比较。中心差分误差在光滑且远离ReLU转折的区域通常随步长平方下降,但太小会受浮点消去影响;当前仅在选定点以一乘十的负七容差核对,不能当作全参数梯度证明。
为避免只在临时八十步模型上检查,本项目还有只读入口python -m rag_lab.audit。它按主检查点保存的seed二十三重新构造初始化网络,与同一个二百二十步模型逐张量比较,十个参数张量都至少一个坐标变化且数值有限;同时核对训练原图散列、配对表散列和训练ID恰为二十个、四个留出ID被排除。该审计不更新模型,也不把测试模型成绩代替主模型。
独立控制有不同作用。零分数二对样本验证损失log二和四项梯度;BM25两文档手算验证公式;RRF对换排名验证并列;实际文档区间重建验证引用;删标签表后重建索引验证运行时数据边界;更改散列与路径穿越验证失效拒答;未知属性、冲突与不可信便笺验证支持政策。测试覆盖这些机制,仍不构成任意输入安全、自然视觉或通用对话质量的保证。
复现报告要保留原始失败。三十九题中神经模式九道文档题失败,三种扰动中平移只有二张身份正确,变暗也有两张失败,灰度有大量不可恢复颜色问题。学生若只看训练loss下降会漏掉最有教学价值的部分。若修复某个模块,应保留旧报告,把新源码、权重、输入和全部新指标绑定到同一版本,不允许对每个图选择不同模型后拼出一张完美表。
工程边界同样具体。当前没有OCR、ASR或音频;没有真实CLIP权重、自然图像泛化、长文语义检索、向量数据库、LLM开放生成或多租户权限系统;上下文预算是正文字符,不是token。模型检查点用torch.load读取可信本项目文件,不能把未知外部pickle当可安全打开的数据。课程目的为可重建的多模态检索与证据流程,这些未实现能力不应藏在一句“以后可扩展”里冒充已经交付。
完成标准不是背出RAG、CLIP和RRF三个名称,而是能解释每个原件怎样被编码、排序、选择、验证和引用,能找出哪一层造成失败,能用相同入口复现一份好结果与一份失败。八章中的算例与项目函数在这个能力目标上相接:第一章定义来源,第二章建立强基线,第三章真正训练,第四章连接检索,第五章约束回答,第六章分层记账,第七章暴露分布失效,本章完成独立交付与复查。
TRY IT YOURSELF
练习一:冻结与再训练
只想核对39题和72扰动,必须运行encoder训练吗?怎样确保不覆盖作者证据?
提示 1
提示 2
对照参考解答
TRY IT YOURSELF
练习二:失效追踪
文件borrowing.md改一字后,已有索引为什么应拒答?重建后是否立即证明新值真实?
提示 1
提示 2
对照参考解答
TRY IT YOURSELF
练习三:部署声明
同学说“通过所有测试,因此支持任意照片和自然问题”。指出推论缺失,并给出当前能成立的验收陈述。