FinanceGym PIT 检索服务器完整搭建指南:从 WARC 语料到可查询的搜索环境 人工智能深度学习NLP计算机视觉强化学习【免费下载链接】google-researchGoogle Research项目地址https://gitcode.com/gh_mirrors/go/google-research点击查看免费下载本指南以 FinanceGym 的 01_run_search_server.md 为主线完整讲解如何将一份原始 Web 语料WARC 归档一步步加工为可用于评测的 Point-in-TimePIT语义检索服务器。读者将掌握提取清洗、向量嵌入、SQLite 文本库构建、FAISS 索引构建与服务启动的全流程并学会用官方 Python 客户端验证服务的可用性。FinanceGym 是一个 point-in-time 的智能体金融研究基准其公开的检索环境financegym.env负责在评测期间为 Agent 提供严格的max_date时间截断检索防止未来信息泄漏参见 README.md。整个检索环境可以概括为一条管道WARC 语料 → 提取嵌入 → SQLite 文本库 → FAISS 索引 → FastAPI 服务本文按照官方示例文档的四个阶段逐一展开并结合仓库源码深入解析每一步的底层机制。一、整体架构与文档定位官方示例文档给出的端到端流程如下web corpus (WARC archives, provided) └─► financegym.corpus.extract_embed (提取干净文本 发布日期 嵌入) └─► financegym.corpus.build_db (构建 SQLite 文本存储) └─► financegym.index.build (构建 FAISS IVF-SQ8 索引) └─► financegym.env.server (FastAPI /search /fetch支持 PIT max_date)其中你负责提供原始语料即输入目录下的所有.warc.gz归档管道负责完成提取extract、嵌入embed、索引index、服务serve。整条管道最终产出的核心文件都集中在同一个输出目录默认为output/search/文件阶段说明embeddings.binextract_embed二进制向量文件8 字节ii头部 n × dim个 float32metadata.jsonlextract_embed每行一条文档元数据JSONtexts.jsonlextract_embed每行一条{doc_id, text}checkpoint.txtextract_embed已完成 WARC 的记录支持断点续跑corpus.dbbuild_dbSQLite 文本库供/fetch以 O(1) 取回全文faiss_index.binindex.buildFAISS 向量索引供/search检索二、环境准备与依赖在动手之前需要确认运行环境满足 docs/setup.md 中列出的要求Python 3.12OpenAI 兼容的嵌入服务financegym.corpus.extract_embed与financegym.env.server需要能访问一个提供/v1/embeddings接口的服务器典型方案是用 vLLM 部署Qwen3-Embedding-4B索引构建资源embeddings.bin通过内存映射mmap读取对超大语料如 1.2 TB 的向量文件也能保持较小的常驻内存GPU 可选但可将 FAISS IVF-SQ8 的 k-means 训练加速约 10–50×LLM 阶段可选若还要跑 graph / questions / curation / judge 等阶段需要GOOGLE_API_KEY。安装命令pip install -e .[dev,faiss-cpu]如需 GPU 加速 k-means 训练将faiss-cpu换成faiss-gpu即可。与本文四阶段管道直接相关的环境变量如下详见 setup.md变量使用者默认值EMBED_URLcorpus.extract_embedhttp://127.0.0.1:8888/v1/embeddingsEMBED_MODEL同上Qwen/Qwen3-Embedding-4BEMBED_DIM同上2560在 extract_embed.py 中可以看到这些默认值均来自环境变量读取这也意味着你完全可以通过设置环境变量来替换嵌入后端例如换成其他兼容 OpenAI 接口的嵌入模型只需保证维度与EMBED_DIM一致。三、阶段 1提取干净文本并嵌入extract_embed3.1 命令与参数官方文档给出的第一步命令# 先启动嵌入服务例如 vLLM 监听 8888 端口 # 再通过 EMBED_URL 指向它。 EMBED_URLhttp://127.0.0.1:8888/v1/embeddings \ python -m financegym.corpus.extract_embed \ path/to/warc/ \ --output output/search/ \ --workers 96参数说明依据 extract_embed.py 中的 argparse 定义参数默认值说明input位置参数—存放.warc.gz的目录递归扫描rglob(*.warc.gz)--outputoutput/search/输出目录--workersmax(1, os.cpu_count() - 16)提取阶段的进程池大小--embed-workers8嵌入阶段的线程数--embed-batch128每个嵌入批次的文本条数--embed-url环境变量EMBED_URLOpenAI 兼容的嵌入接口--embed-model环境变量EMBED_MODEL嵌入模型名--embed-dim环境变量EMBED_DIM2560向量维度写入embeddings.bin头部3.2 底层机制三段式流水线从源码结构看extract_embed.py 的run函数实现了一个三阶段并发流水线设计目标是在提取器还在运行时就让嵌入 GPU 保持饱和Reader单线程逐个流式读取 WARC 记录使用warcio的ArchiveIterator只保留response类型且Content-Type含html的记录取出WARC-Target-URI与WARC-Date将(warc_name, url, crawl_date, html)放入有界队列pool_aExtractors进程池每个 worker 对 HTML 调用extract_article——先用trafilatura提取正文、用htmldate探测发布日期两者不可用时退化为简单的标签剥离正文不足MIN_TEXT_LEN 100字符的记录直接丢弃extract_embed.py提取结果放入pool_bEmbedders线程池按embed_batch_size攒批后调用embed_batchextract_embed.py——即向/v1/embeddings发{model: ..., input: texts}请求并按返回的index排序取回向量单批失败自动重试 3 次指数退避1s、2s。值得注意的细节批次顺序保证写入端有一个_writer线程按batch_id严格顺序落盘因此embeddings.bin、metadata.jsonl、texts.jsonl三份文件行/条严格一一对应——这是后续build_db能够“锁步”读取两个 JSONL 的前提extract_embed.py文本长度上限MAX_TEXT_LEN 120_000约 4 万 token源码注释明确指出这不是截断而是安全上界doc_id 生成写入时按顺序生成doc_{next_doc_id}形式。3.3 二进制格式与断点续跑embeddings.bin的格式为头部 8 字节小端序(n, dim)struct.pack(ii, n, dim)随后是n × dim个 float32 向量extract_embed.py。官方将Qwen3-Embedding-4B2560 维固定为基准嵌入器以保证可复现性详见 docs/reproducibility.md。断点续跑依赖checkpoint.txt每完成一个 WARC 就追加一行文件名重新运行时run会读取 checkpoint跳过已完成文件并把embeddings.bin以追加模式rb、seek 到末尾继续写入metadata.jsonl/texts.jsonl同样追加extract_embed.py。这意味着中途失败无需从头重来。四、阶段 2构建 SQLite 文本库build_db4.1 命令与产物python -m financegym.corpus.build_db --input output/search/产物为output/search/corpus.db。4.2 表结构与写入策略build_db.py 中定义了单表docs及三个索引CREATE TABLE docs ( idx INTEGER PRIMARY KEY, doc_id TEXT NOT NULL, url TEXT, domain TEXT, pub_date TEXT, crawl_date TEXT, text_len INTEGER, text TEXT ); CREATE UNIQUE INDEX idx_doc_id ON docs(doc_id); CREATE INDEX idx_domain ON docs(domain); CREATE INDEX idx_pub_date ON docs(pub_date);idx_pub_date索引为 PIT 时间过滤服务服务端/search在启用max_date时依赖pub_date做时间截断虽然过滤发生在应用层但索引保证了元数据/全文检索场景下的可用性。构建过程metadata.jsonl与texts.jsonl以锁步方式逐行zip读取——这正依赖上一阶段“行与行一一对应”的不变式build_db.py每攒满batch_size 10_000行执行一次executemany批量插入并提交构建前设置一批批量导入优化 PRAGMAjournal_modeWAL、synchronousOFF、cache_size-1000000、temp_storeMEMORY先批量插完所有行再统一创建索引最后返回corpus.db的路径build_db.py。这个文本库的意义在于/fetch端点可以按doc_id以 O(1) 方式取回全文而不必把全部正文放进内存服务端内存里只保留轻量元数据。五、阶段 3构建 FAISS 索引index.build5.1 命令与参数python -m financegym.corpus.build_db --input output/search/python -m financegym.index.build --input output/search/ --index-type ivf_sq8产物为output/search/faiss_index.bin。build.py 支持四种索引类型--index-type说明适用场景ivf_sq8默认IVF 8-bit 标量量化内积度量与官方 FinanceEnv 契约一致的规范索引ivf_flatIVF 无量化内积度量精度优先、内存可承受时flat_sq8全量扫描 SQ8 量化小语料冒烟测试flat全量精确扫描IndexFlatIP小语料冒烟测试另有--nlistIVF 聚类数默认None自动计算与--nprobe查询时探测的聚类数默认32两个可选参数。5.2 底层实现要点自动 nlistauto_nlist(nvecs) clamp(int(sqrt(nvecs)), 256, 65_536)即遵循sqrt(n)经验法则并夹取到合理区间让极小和极大的语料都能得到合理索引build.py内存映射读取memmap_embeddings用np.memmap读取 8 字节头部之后的 float32 载荷因此超大语料超过物理内存也能构建索引build.py训练集采样固定随机种子42从全部向量中无放回抽取min(nvecs, max(nlist*256, 1_000_000))条做 k-means 训练GPU 加速若faiss.get_num_gpus() 0自动把聚类索引迁移到 GPU 上训练训练完成后释放build.py逐批添加以ADD_BATCH 1_000_000条为一批faiss.normalize_L2归一化后add训练完成后设置nprobe 32规范契约官方契约固定为Qwen3-Embedding-4B2560 维、L2 归一化→ IVF-SQ8 nprobe32其他索引类型仅用于小规模验证。六、阶段 4启动服务并验证env.server EnvClient6.1 启动命令python -m financegym.env.server --data-dir output/search/ --host 0.0.0.0 --port 8889参数--data-dir默认output/search/、--host默认127.0.0.1、--port默认8889。服务启动时会调用ServerState.from_disk加载三样东西server.py元数据逐行读取metadata.jsonl放入内存列表meta用于搜索结果的 url/domain/pub_date 展示SQLite 文本库若corpus.db存在则打开连接并设置约 4GB 的 page cache 与 8GB 的 mmap缺失时记录警告/fetch将返回空FAISS 索引若faiss_index.bin存在则faiss.read_index载入并尝试把 IVF 索引的nprobe提升到 32缺失时/search将返回 503。6.2 REST 接口契约服务采用 FastAPI 实现固定暴露四个端点server.py端点方法功能/searchPOST语义检索支持可选max_datePIT 时间截断/fetchPOST按doc_id取回全文/statsGET返回total_docs/index_loaded/db_loaded摘要/healthGET存活探针索引就绪返回{status: ok}否则loading/search的请求体server.py{ query_embedding: [0.1, 0.2, ...], k: 10, max_date: 2025-06-30 }PIT 过滤的实现要点server.py当提供max_date时服务端先把召回数放大为k * 5retrieve_k k*5再按pub_date max_date逐条过滤直到凑满k条——这样既满足“绝不泄漏未来信息”的契约又避免因时间过滤导致召回不足。查询向量会先做 L2 归一化再与 IVF 索引做内积检索。6.3 用 Python 客户端验证官方示例直接使用financegym.env.client.EnvClientclient.pyfrom financegym.env.client import EnvClient client EnvClient(http://localhost:8889) print(client.stats()) # {total_docs: ..., index_loaded: True, db_loaded: True} print(client.health()) # {status: ok}EnvClient是对四个端点的薄封装还提供带 PIT 截断的语义检索与全文取回hits client.search(query_embeddingembedding, k5, max_date2025-06-30) doc client.fetch(hits[0][doc_id])其中search返回的每条命中包含doc_id、url、domain、pub_date、score与text_preview默认截取正文前 200 字符见 server.pyfetch返回完整文档字段。七、一键脚本与阶段跳过控制官方还提供了整个序列的一键封装脚本 scripts/build_search_env.sh其内部就是按“extract → build_db → index.build → server”顺序依次调用scripts/build_search_env.sh脚本支持的环境变量与默认值变量默认值说明WARC_DIRoutput/corpus/warc你提供的.warc.gz目录SEARCH_DIRoutput/search所有中间产物与最终索引/库的落盘目录INDEX_TYPEivf_sq8传给financegym.index.buildHOST/PORT127.0.0.1/8889服务绑定地址与端口PYTHONpythonPython 解释器SKIP_EMBED/SKIP_DB/SKIP_INDEX/SKIP_SERVE空置为任意真值即跳过对应阶段跳过指定阶段例如嵌入已完成、只需重建索引并服务SKIP_EMBED1 SKIP_DB1 scripts/build_search_env.sh脚本以set -euo pipefail运行任一阶段失败即中断退出方便定位问题。若只想启动服务索引与数据库均已就绪则SKIP_EMBED1 SKIP_DB1 SKIP_INDEX1并单独指定HOST/PORT。八、运行验证与常见排查健康检查client.health()应返回{status: ok}若返回loading说明 FAISS 索引尚未加载成功。资源加载确认client.stats()中index_loaded: True且db_loaded: True才说明向量索引与文本库都已就绪total_docs应与extract_embed阶段写入的文档数一致。索引缺失faiss_index.bin不存在时/search会返回 503源码中显式抛出HTTPException(503, Index not loaded)。文本库缺失corpus.db不存在时/fetch返回空文本且启动日志会给出“SQLite DB missing”警告。断点续跑若嵌入阶段中断重跑extract_embed会依据checkpoint.txt跳过已完成的 WARC并把新向量追加写入既有三份文件。硬件资源参考详见 setup.md嵌入阶段磁盘约为 WARC 体积的 10 倍、且为 GPU 密集型build_db磁盘约等于texts.jsonl总大小IVF-SQ8 索引文件约为embeddings.bin的 40%服务进程只需让元数据与索引常驻内存。整条管道的运行顺序与阶段衔接还可进一步参考 docs/pipeline.md。结语至此你已经可以从一份 WARC 语料出发依次完成文本提取与嵌入、SQLite 文本库构建、FAISS 索引构建、服务启动与客户端验证最终得到一个带严格max_date时间截断的 PIT 语义检索环境。这套环境正是 FinanceGym 评测 Agent 时的公共检索入口——四阶段管道、二进制/JSONL/SQLite 三种落盘格式、断点续跑机制以及/search中“放大召回再时间过滤”的 PIT 实现共同保证了检索环境对每个 Agent 都公平、可复现且无未来信息泄漏。赞分享人工智能深度学习NLP计算机视觉强化学习【免费下载链接】google-researchGoogle Research项目地址https://gitcode.com/gh_mirrors/go/google-research点击查看免费下载相关推荐FinanceGym 技术指南构建可验证的点位时间金融深度研究基准与 PIT 检索环境FinanceGym 技术指南构建可验证的点位时间金融深度研究基准与 PIT 检索环境 FinanceGym 是 FinanceHarness 项目中负责 基人工智能深度学习NLP计算机视觉强化学习用 CocoIndex 构建基于 LanceDB 的无服务器语义搜索索引从 Markdown 到可查询向量库的完整实战用 CocoIndex 构建基于 LanceDB 的无服务器语义搜索索引从 Markdown 到可查询向量库的完整实战 本篇技术指南讲解如何在 CocoInd人工智能大模型RAGAI AgentAgent 记忆数据工程流处理TTSFM CLI工具使用教程命令行快速生成高质量语音文件TTSFM CLI工具使用教程命令行快速生成高质量语音文件 TTSFM CLI工具是一款强大的文本转语音命令行工具兼容OpenAI TTS服务接口提供免费人工智能深度学习NLP计算机视觉强化学习创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考