项目

一般

简介

02-全局可复用模块清单 » 历史记录 » 版本 2

Huarui Lin, 2026-04-24 09:24

1 1 Huarui Lin
# 全局清单
2
3
### 一、 全局可复用模块清单 (DRY 原则绝对落地)
4
为了防止几千行代码中出现逻辑分叉导致静默 Bug,以下 4 个模块必须在工程中作为**单一真实来源** 被各阶段强依赖调用。
5
6
| 模块契约名 | 物理路径映射 |
7
| :--- | :--- |
8
| `core.physical_storage_contract` | `src/core/storage/contract.py` |
9
| `core.stream_engine` | `src/core/stream/engine.py` |
10
| `core.standardization_math` | `src/core/math/zscore.py` |
11
| `core.duckdb_time_aligner` | `src/core/sql/aligner.py` |
12
13
#### 1. `core.physical_storage_contract` (物理存储死锁契约)
14
**被依赖方**:S2, S3, S4, S5.1 参数落盘。
15
**核心职责**:封装所有 Polars 的 `sink_parquet` 动作。
16
*   **强制入参**:`df`, `target_path`, `partition_cols=None` (可选按年拆分)。
17
*   **内部死锁逻辑**:无论传入什么,最终执行前必定被强制注入 `.sort(by=["net_value_date", "fund_id"], maintain_order=False)`,必定注入 `row_group_size=100000`, `compression="zstd"`, `compression_level=7`。任何业务侧企图绕过此模块直接调用 `.write_parquet()` 的代码,必须在 Code Review 中被一票否决。
18
#### 2. `core.stream_engine` (按年流式安全池引擎)
19
**被依赖方**:S2 长缺失切断、S3 特征计算、S5 Spearman 共线性。
20
**核心职责**:封装“年份外层循环 + 内存安全断言 + 释放”的拓扑。
21
*   **核心方法**:`stream_by_year(file_pattern, process_year_func)`
22
*   **内部死锁逻辑**:内部执行年份循环,读取单年数据后,**强制断言内存峰值 < 3GB**(通过 `psutil` 轮询采样),执行业务传入的 `process_year_func`,执行完毕后强制 `del` 释放,进入下一年。彻底杜绝业务侧忘记释放内存导致的 cgroup 击穿。
23
#### 3. `core.standardization_math` (标准化纯数学内核)
24
**被依赖方**:S5 训练前标准化、S6 推理服务。
25
**核心职责**:提供与语言/框架无关的绝对一致的 Z-Score 转换逻辑。
26
*   **核心方法**:`apply_zscore(feature_matrix, param_matrix)` -`standardized_matrix`
27
*   **内部死锁逻辑**:
28
    *   接收的输入形状被抽象为 `(N, 38)`(S5 N=3000万,S6 N=1000)。
29
    *   内部强制执行 **IEEE 754 除零拦截**(`std == 0 -None`)。
30
    *   内部强制执行 **MAD 裁剪**(`clip(lower, upper)`)。
31
    *   **复用意义**:S5 训练和 S6 推理绝对共用这一段底层 NumPy 广播逻辑,从数学根源上抹除“训练分布与推理分布不一致”的终极灾难。
32
#### 4. `core.duckdb_time_aligner` (DuckDB 无状态对齐器)
33
**被依赖方**:S2 粗筛阶段。
34
**核心职责**:生成唯一合法的 SQL 片段。
35
*   **核心方法**:`get_week_alignment_sql(date_col)`
36
*   **内部死锁逻辑**:返回硬编码的纯数学整数除法 SQL 实体:`DATE '1970-01-05' + ((CAST(col AS BIGINT) - CAST(DATE '1970-01-05' AS BIGINT)) / 7) * 7`。彻底封杀任何地方手写字符串拼接日期函数的可能。
37
---
38
### 二、 企业级 CI/CD 强制红线清单 (阻断交付)
39
以下检查项必须作为 Git Pre-commit Hook 或 GitHub Actions 流水线的绝对门禁。任何一条不通过,严禁合并入主分支。
40
#### 红线 1:Pandas 零容忍扫描 (AST 静态分析)
41
*   **实施手段**:在 CI 中引入 Python 的 `ast` 模块扫描所有 `.py` 文件的抽象语法树。
42
*   **拦截逻辑**:如果发现 `import pandas` 或 `from pandas` 的节点,直接报错 `FATAL: Pandas dependency detected. Pipeline corrupted.`。
43
*   **防御目标**:防止研发在局部图方便引入 Pandas,破坏 Polars 全局 Lazy 优化图。
44
#### 红线 2:Schema 对称差拦截 (Pydantic 运行时单测)
45
*   **实施手段**:在 `tests/test_schema_symmetry.py` 中,硬编码 38 维特征名字符串集合,以及 S2(5列)、S3(42列)、S4(4列) 的长度要求。
46
*   **拦截逻辑**:在 CI 中拉起一个极小的 Mock 数据流,跑完 S2->S3->S4 的主流程骨架,在产出节点使用 Pydantic 强校验 `df.columns` 与硬编码集合的**对称差集**。差集如果不为空,直接 `pytest.exit("Schema Drift Detected!")`。
47
#### 红线 3:EWM / OLS 金色单测 (精度基线死锁)
48
*   **实施手段**:使用 NumPy 预生成一组包含精确已知输出的基准时序数据(如纯线性递增序列、已知频率的正弦波),保存在 `.npy` 文件中。
49
*   **拦截逻辑**:CI 单测中调用我们手写的 `scipy.signal.lfilter` (EWM) 与纯标量展开式 (OLS),比对输出结果与 `.npy` 基线。允许的浮点误差死锁为 `1e-7`。一旦底层库升级导致精度漂移越过此阈值,直接阻断流水线。
50
#### 红线 4:工程治理正则扫描 (魔法数字猎手)
51
*   **实施手段**:使用 `grep -En "(1\.4826|0\.90|maintain_order=True|gc\.collect|partition_by\(as_dict=True\))" src/`。
52
*   **拦截逻辑**:
53
    *   `1.4826` 必须来自 `config.yaml`。
54
    *   `maintain_order=True` 违反 Radix Sort 红线。
55
    *   `gc.collect()` 违反 mimalloc 红线。
56
    *   `partition_by(as_dict=True)` 在非安全池内触发 OOM 红线。
57
    *   命中任何一条,CI 直接失败。
58
---
59 2 Huarui Lin
60 1 Huarui Lin
### 三、 系统最终交付物理清单
61
当你完成所有开发后,产出的工程目录中必须严格包含以下物理文件,缺一不可:
62 2 Huarui Lin
63 1 Huarui Lin
**【数据湖层】**
64 2 Huarui Lin
65 1 Huarui Lin
*   `s2_{year}.parquet` (按年拆分,Zstd7,Row Group=10万,严格5列)
66
*   `s3_{year}.parquet` (按年拆分,Zstd7,严格42列)
67
*   `s4_{year}.parquet` (按年拆分,Zstd7,严格4列)
68 2 Huarui Lin
69 1 Huarui Lin
**【模型与参数层】**
70 2 Huarui Lin
71 1 Huarui Lin
*   `standardization_params_wide.parquet` (S5 训练专用,宽表形态,已 shift(1))
72
*   `standardization_params.parquet` (S6 推理专用,长表形态,已自然日 Ffill,已按 `["feature_name", "date"]` 物理排序)
73
*   `model.txt` (LightGBM LambdaRank 最终重训模型实体)
74 2 Huarui Lin
75 1 Huarui Lin
**【微服务层】**
76 2 Huarui Lin
77 1 Huarui Lin
*   `s6_inference/` (独立 FastAPI 仓库或目录,内含 `main.py`,启动即加载全局变量,接收 `(N, 38)` 矩阵,吐出 `N` 维得分)
78 2 Huarui Lin
79 1 Huarui Lin
**【配置与红线层】**
80 2 Huarui Lin
81 1 Huarui Lin
*   `config.yaml` (业务可配:MAD系数、共线性阈值、Spearman模式)
82
*   `core/constants.py` (物理死锁:52周、1970基准日、Parquet压缩级别)
83
*   `.github/workflows/ci.yml` (集成上述四大红线拦截器)
84
*   `configs/config.yaml` (业务超参唯一真实来源,含 D-1 白名单与 MAD 系数)。
85 2 Huarui Lin
86 1 Huarui Lin
---
87
**全链路拆解完毕。** 
88 2 Huarui Lin
89 1 Huarui Lin
从 S0 脚手架到 S6 矩阵推理,从 DuckDB 纯数学偏移到 50GB cgroup 下的微线程 GIL 防线,这套拓扑没有留下任何“自作聪明”的余地。你可以直接将这 5 个阶段的拆解发给研发团队作为**史诗级需求的最细粒度 Task 拆解**开始排期。