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