本文件用于帮助后续 coding agent 快速理解 statgpu 项目。它是项目导览,不是用户手册;修改代码前仍应阅读相关源码和文档。
自动开发的阻塞 gate、退出状态和 review/fix 协议以 .claude/workflows/new-module-dev.md 及 .claude/skills/ 下对应 skill 为准。若本文和 .claude workflow/skill 有冲突,开发任务中优先执行 .claude 的硬约束,并在结果中说明差异。
statgpu 是一个 GPU 加速的统计计算 Python 库,提供接近 scikit-learn 的 fit / predict / score API。项目重点是统计建模、推断、特征选择、生存分析和非参数方法,并通过 NumPy、CuPy、PyTorch 后端在 CPU/GPU 间切换。
包版本和顶层导出位于 statgpu/__init__.py。项目元数据、依赖和 pytest 配置位于 pyproject.toml。
statgpu/__init__.py: 顶层公共 API 汇总,包括模型、后端、推断、特征选择和非参数方法。statgpu/_base.py: estimator 基类,包含设备解析、后端获取和数组转换逻辑。statgpu/_config.py: 全局设备管理,支持cpu、cuda、torch、auto。statgpu/backends/: NumPy、CuPy、Torch 后端抽象和自动选择逻辑。statgpu/solvers/: 通用优化求解器(FISTA、FISTA-BB、FISTA-LLA、Newton、L-BFGS、ADMM)。statgpu/penalties/: L1、L2、ElasticNet、SCAD、MCP、adaptive/group penalty 注册表。statgpu/glm_core/: GLM loss、family/link、IRLS、融合 kernel。statgpu/cross_validation/: 通用 CV 框架(CVEstimatorBase、kfold_indices、hash_cv_data)。statgpu/linear_model/: 线性模型 API 层,含wrappers/(13 个模型)、penalized/(mixin 架构)、cv/(CV wrappers)、legacy/。statgpu/survival/: CoxPH 和 CoxPHCV,含 Breslow/Efron ties 及 GPU 相关实现。statgpu/inference/: 分布 API、多重检验、p 值合并、bootstrap、permutation test。statgpu/nonparametric/: KDE、核回归、带宽选择、核岭回归、样条。statgpu/feature_selection/: knockoff 特征选择相关实现。statgpu/core/formula/: 可选 formula/dataframe 接口,依赖patsy/pandasextra。
所有当前 estimator 以 device 参数控制计算路径:
device="cpu": 使用 NumPy CPU 路径。device="cuda": 使用 CuPy CUDA 路径;CuPy/CUDA 不可用时应报错,不静默回退 CPU。device="torch": 使用 Torch CUDA 路径;Torch CUDA 不可用时应报错,不使用 Torch CPU 作为隐式回退。device="auto": 唯一允许自动选择可用后端的模式,通常优先 CuPy,其次 Torch CUDA,最后 NumPy。
保持“显式设备不静默回退”的约束很重要。新增功能时应复用 BaseEstimator._get_backend()、_to_array()、后端抽象和现有 device 语义。
所有持有 GPU 缓存张量的 estimator 必须实现 gpu_memory_cleanup 模式:
- 构造函数接受
gpu_memory_cleanup: bool = False参数。 - 实现
_cleanup_cuda_memory()和_cleanup_torch_memory()方法,在gpu_memory_cleanup=True时释放 CuPy/Torch 缓存。 - 实现
__del__确保对象被 GC 时触发清理。 - 在公开方法(如
pdf()、predict()、score())末尾调用清理,而非fit()末尾(fit 后的缓存需供后续 predict 使用)。
参考实现:statgpu/linear_model/_logistic.py:134-145。
def _cleanup_cuda_memory(self):
if not self.gpu_memory_cleanup:
return
try:
import cupy as cp
cp.get_default_memory_pool().free_all_blocks()
cp.get_default_pinned_memory_pool().free_all_blocks()
except Exception:
pass
def _cleanup_torch_memory(self):
if not self.gpu_memory_cleanup:
return
try:
import torch
torch.cuda.empty_cache()
torch.cuda.synchronize()
except Exception:
pass以下规则来自 dev/plans/PLAN_UNIFIED.md 和 .claude workflow/skill 中较稳定的项目约束,适用于后续功能开发和重构:
- 所有新增或修改的统计方法必须同时实现 NumPy、CuPy、Torch 三后端;CPU-only 工作不算完成。若某端暂不可行,必须获得用户明确批准,并记录原因、用户可见失败行为、测试 skip 条件和后续补齐路径。
- 显式
device="cuda"或device="torch"不允许静默回退 CPU;fallback、approximate inference、dtype/device 变化必须是公开契约的一部分,并在错误、warning 或结果字段中可见。 - 直接
fit()支持的 tunable loss x penalty 能力,默认也必须支持 CV 层,包括 alpha/lambda/C 路径、fold scoring、best parameter selection 和 refit;除非该能力明确 non-tunable 或用户批准延期。 - 公共统计 estimator 若暴露
compute_inference、summary()、covariance、standard errors、p-values、confidence intervals,或该模型家族通常要求推断,则必须实现 inference 或显式声明 estimation-only,并补清晰错误行为、测试、文档和后续任务。 - Formula-facing 方法必须验证 R-style/patsy 兼容,包括 intercept、categorical reference level、interaction/transform、missing data、列名和列顺序;暂不支持的语法要有明确失败模式和文档说明。
- 新增 inference、stopping rule、影响数值的 memory behavior 或 estimator 行为时,外部基线检查应尽可能全面:推断/统计优先对齐
statsmodels,估计器和预测一致性优先对齐sklearn,关键统计方法补充 R 基线;能覆盖 coef/bse/p/CI/AIC/BIC/LLF、预测、目标函数或 KKT 的场景应尽量覆盖。 - 外部比较必须使用显式对齐设置,包括相同特征集、ties/solver、正则化参数和收敛参数,如
alpha、C、max_iter、tol。 - 外部比较前必须确认 objective normalization 和 penalty scale。若
statgpu优化n^{-1} sum_i loss_i + lambda * penalty,而外部框架优化sum_i loss_i + lambda * penalty,测试应使用等价 penalty 映射(如lambda_external = n * lambda),不要为了强行对齐外部框架而修改statgpu的 loss 定义。 - strict inference 是默认主线;strict 失败默认应报错,只有用户显式启用 fallback/downgrade 时才降级。
- 当前 strict 对齐阈值基线:
coef <= 1e-6、bse <= 1e-3、p-value <= 5e-2。 - 关键 inference 输出字段应保持 CPU/GPU 一致,例如
coef、bse、t/z、p、CI、AIC/BIC/LLF等。 - CUDA 分层规则保持有效:模型层不要到处散落直接
cupyimport,优先复用statgpu/backends/、BaseEstimator和已有后端工具。 - 每个新方法的准入标准是 implementation、tests、external comparison 或 benchmark、docs update 同步完成;性能相关 benchmark 脚本优先放
dev/benchmarks/,结果写入results/*.json,GPU 计时必须包含 CuPy/Torch synchronize。 - 新模型推荐流程:先明确接口契约,再做 CPU 实现,然后补 GPU 路径和 strict inference,接着补导出、测试、外部一致性、benchmark、英文优先/中文跟进文档。
- 用户可见能力变更后,要保持 README、USAGE、英文/中文 docs 和 changelog 的能力描述一致。
- 工程 gate 的方向是 nightly 覆盖 lint/type/test,monthly stable 额外覆盖外部一致性矩阵、benchmark non-regression 和文档同步;本地改动至少要说明已跑或未跑的相关验证。
dev/plans/PLAN_UNIFIED.md 对文档有硬要求。新增或修改用户可见能力时,文档不能只写一句 API 说明,应按能力范围补齐以下内容:
- 文档更新顺序默认 EN-first、CN-follow:先更新
docs/en/和英文入口,再同步docs/cn/中文页或中文相关入口。 - README、USAGE、EN/CN docs、changelog 中的能力声明必须一致,不能出现某处宣称支持、另一处仍写未支持的状态。
- 模型页应尽量包含:Overview、Path、Objective Function、Estimating Equation、Covariance/Inference、Parameters、CPU+GPU Examples、strict/approx difference、Outputs、FAQ、External Validation、References。
- 涉及 strict/approx 两条路径时,必须明确默认策略、fallback 条件、数值阈值或适用边界,避免让用户误以为 approximate 是默认严格推断。
- 涉及设备或后端时,示例应覆盖 CPU、CuPy/CUDA、Torch 中适用的路径;暂不支持的后端要写清限制。
- 涉及外部基线时,文档应说明对齐对象和设置,例如
statsmodels、sklearn、R 包、solver/ties/regularization/tolerance 等。 - benchmark 或远程实验结果进入文档时,应附可审计产物路径,例如
results/*.json和简短 markdown summary,而不是只写口头结论。 - 引用统计方法、论文、R 包或外部 API 时,应保留 References 或链接,避免只写实现细节不写统计来源。
后续开发中较常被复用的两块代码是:
statgpu/backends/: 后端抽象、数组转换、可用性检测和 NumPy/CuPy/Torch 选择逻辑。新增模型或算法时,优先通过这里的接口处理跨后端计算,不要在业务模块里重复写 backend 分支。statgpu/inference/中和 distribution 有关的代码,尤其是_distributions_backend.py及get_distribution()等导出接口。新增统计推断、p 值、置信区间或分布函数需求时,先检查这里是否已有统一实现。
README.md: 项目总体说明、安装方式、快速示例和功能概览。docs/en/usage.md: 英文使用入口。docs/cn/usage.md: 中文使用入口。docs/en/: 英文文档,包括 quickstart、guides 和各模型说明。docs/cn/: 中文文档目录。docs/en/models/README.md: 模型覆盖范围和当前限制的较新摘要。docs/en/guides/device-and-memory.md: 设备选择、GPU 内存和后端规则。
新增或修改用户可见能力时,通常需要同步更新相关 docs/en/models/*.md、docs/cn/models/*.md、docs/en/changelog.md、docs/cn/changelog.md 或入口文档。
项目有三份 changelog,定位不同:
| 文件 | 定位 | 读者 | 详细程度 |
|---|---|---|---|
CHANGELOG.md(根目录) |
PR 级摘要 | 开发者、贡献者 | 简洁,每个 PR 1-5 行 |
docs/en/changelog.md |
用户级详述 | 用户、研究者 | 详细,含性能数据、代码示例、验证产物 |
docs/cn/changelog.md |
用户级中文详述 | 中文用户、研究者 | 与英文详细版结构一致,中文自然表述 |
三份文件按变更类型同步更新,内容不机械重复但能力声明必须一致。
# Changelog
All notable changes to statgpu are documented here, organized by date and PR.
## YYYY-MM-DD
### PR #NN — 简短标题(不超过 60 字符)
- 变更描述 1(英文,句首动词过去式)
- 变更描述 2
### PR #MM, #LL — 合并标题
- 变更描述
---
## GPU Performance Milestones
### vX.X — 标题
- 关键指标规则:
- 按日期分组,同一日期多个 PR 按编号倒序(最新在前)
- 每个 PR 1-5 行描述,只写"做了什么",不写"为什么"和"怎么做"
- 合并相关 PR:
PR #61, #60, #59 — 标题 - GPU Performance Milestones 单独 section,记录重大性能版本
采用 Keep a Changelog 风格,按类别组织:
# Changelog
> Language: English
> Last updated: YYYY-MM-DD
> Switch: [Chinese](../changelog.md)
## YYYY-MM
### Added (YYYY-MM-DD)
- **功能标题**:
- 详细描述(what + why)
- 支持的后端/场景
- 文件变更列表
- 代码示例(如适用)
### Fixed (YYYY-MM-DD ~ YYYY-MM-DD)
- **Bug 标题**:
- Root cause 分析
- 影响范围
- 修复方式
- 验证结果
### Optimized (YYYY-MM-DD)
- **优化标题**:
- 优化内容
- 性能数据(硬件型号、数据规模、提速倍数)
- 验证产物路径(`results/*.json`)
### Improved (YYYY-MM-DD)
- **改进标题**:
- 改进内容
- 对比数据
### Validation (YYYY-MM-DD)
- 验证覆盖范围
- 测试结果(X/Y passed)
- 远程环境信息规则:
- 按月份分组(
## YYYY-MM),月内按日期和类别分 - 五个类别:
Added、Fixed、Optimized、Improved、Validation Added:新功能、新模型、新 API。必须包含:功能描述、支持的后端、文件列表、代码示例Fixed:Bug 修复。必须包含:root cause、影响范围、修复方式、验证结果Optimized:性能优化。必须包含:优化内容、性能数据(含硬件型号和数据规模)、验证产物路径Improved:非功能性改进(代码质量、文档、测试覆盖等)Validation:验证覆盖范围扩展(新测试、新 benchmark、远程验证)- 性能数据必须附硬件信息(如
Tesla P100、n=5000, p=500) - 验证产物路径用
results/*.json或dev/tests/*.py格式 - 破坏性变更在
Fixed或Added中用**breaking**前缀标注
结构与英文版完全相同,类别名使用中文:
| 英文 | 中文 |
|---|---|
### Added |
### 新增 |
### Fixed |
### 修复 |
### Optimized |
### 优化 |
### Improved |
### 改进 |
### Validation |
### 验证 |
规则:
- 类别名统一用中文,不要出现
### Fixed和### 修复混用的情况 - 技术术语保持英文(如
FISTA、CuPy、L-BFGS、PenalizedGLM_CV) - 文件路径、代码、数值、硬件型号保持英文
- 描述用中文,句式自然,不要逐字翻译英文版
- 头部元信息使用中文:
> 语言:中文 > 最后更新:YYYY-MM-DD > 切换:[English](en/changelog.md)
| 变更类型 | CHANGELOG.md |
docs/en/changelog.md |
docs/cn/changelog.md |
|---|---|---|---|
| 新功能 | 1 行 PR 标题 + 1-2 行描述 | Added 下完整描述 + 代码示例 + 文件列表 |
新增 下对应内容(中文描述) |
| Bug 修复 | 1 行 PR 标题 + 1 行描述 | Fixed 下 root cause + 影响 + 修复 + 验证 |
修复 下对应内容(中文描述) |
| 性能优化 | 1 行 PR 标题 + 提速倍数 | Optimized 下完整数据 + 硬件 + 产物路径 |
优化 下对应内容(中文描述) |
| 重构 | 1 行 PR 标题 | Improved 下简述(或不写) |
改进 下对应内容(或不写) |
| 文档 | 1 行 PR 标题 | Improved 或不写 |
改进 或不写 |
| 破坏性变更 | **breaking** 前缀 + 迁移路径 |
Fixed 或 Added 中标注 + 迁移路径 |
修复 或 新增 中标注 + 迁移路径 |
- PR 合并时:立即更新
CHANGELOG.md(根目录) - 版本发布前:从
CHANGELOG.md汇总到docs/en/changelog.md(英文详细版),同步更新docs/cn/changelog.md(中文详细版) - 性能里程碑:benchmark 全量通过后,同步更新三份文件的 GPU Performance Milestones
- 中文版更新顺序:先写英文版,再写中文版(避免翻译返工)
根目录 CHANGELOG.md(简洁):
### PR #55 — Core GLM solver, backends, penalties, inference (PR-A)
- 7 GLM families: squared_error, logistic, poisson, gamma, inverse_gaussian, negative_binomial, tweedie
- 10 penalties: none, l1, l2, elasticnet, scad, mcp, adaptive_l1, group_lasso, group_mcp, group_scad
- 6 solvers: irls, fista, fista_bb, admm, lbfgs, newton详细版 docs/en/changelog.md(完整):
### Fixed (2026-05-20)
- **v23c: L-BFGS fused penalty gradient fix**:
- Root cause: `lbfgs_solver` fused GLM path computed loss-only gradient, missing penalty gradient
- L-BFGS converged to unregularized solution (`loss_grad ≈ 0`) instead of `loss_grad + α·coef = 0`
- Fix: add `_smooth_penalty_gradient(penalty, coef)` after each `_fused_glm_value_and_gradient` call
- Affected: all GLM families + smooth penalties (L2, ElasticNet)
- Impact: 9 MISMATCH cases fixed (max|diff| from 1e-01~1e-02 down to 1e-04~1e-08)
- Full benchmark: 1043/1043 ALL PASS
- Files modified: `statgpu/glm_core/_solver.py`pyproject.toml 将 pytest 的 testpaths 配置为 dev/tests。优先运行与改动相关的针对性测试,例如:
pytest dev/tests/test_linear.py
pytest dev/tests/test_penalties_and_exports.py
pytest dev/tests/test_distributions_backend.py本地 conda base 环境只用于导入测试和轻量 smoke test,例如确认 import statgpu、顶层 API 导出和纯 CPU 基础路径没有明显断裂。精度测试、运行时间测试、GPU 数值一致性、benchmark、R 对比和远程环境相关验证,应在通过 dev/scripts/remote_config.py 配置的远程 GPU 环境中进行;当前常用环境是 Matpool 远程服务器的 myconda。
GPU、远程、benchmark、R 对比类脚本较多,通常不应在本地无目的地全量运行。涉及远程测试时,优先使用 dev/scripts/remote_config.py 或未跟踪的 local config/环境变量提供连接信息,不要把服务器凭据写入代码、文档、测试、memory、.claude/settings.json 或提交记录。
dev/tests/是主要测试目录,但其中也包含大量远程、debug、benchmark、runner 脚本;选择测试时要看文件名和内容。dev/benchmarks/、results/、tmp/、statgpu.egg-info/、__pycache__/等多为实验产物、构建产物或临时文件,不要把它们当作核心库代码。.gitignore已排除很多本地、远程和 benchmark 产物;新增临时脚本或大结果文件前先检查是否应被跟踪。- 不要提交远程服务器凭据、密码、token 或本地环境配置。远程配置应使用
dev/scripts/remote_config.py、环境变量或未跟踪的 local config。 - 当前仓库可能存在未提交改动和未跟踪调试文件。修改前先看
git status,只触碰任务相关文件,不要回退他人改动。
- 优先沿用现有 sklearn 风格 API、后端抽象、solver/penalty 注册表和文档结构。
- 新增 estimator 时尽量继承或模仿现有
BaseEstimator、linear_model和glm_core模式。 - 新增后端相关逻辑时,要同时考虑 NumPy、CuPy、Torch 的数组类型、设备纯度和结果转回 NumPy 的边界。
- 新增统计方法时,至少补充针对性单元测试;若涉及 GPU 或性能,再补充 benchmark 或远程验证脚本。