Lightweight web UI for managing, running, and monitoring Python experiments.
Project description
pyruns
English | 简体中文
Python 实验管理 Web UI 工具:参数可视化编辑、网格批量调度、实时日志流式查看与指标聚合导出
✅ 零侵入兼容 argparse · ✅ 命令行模式兼容任意框架 · ✅ 全流程本地运行
Pyruns 为 Python 脚本提供基于本地浏览器的图形界面。其主要功能包括:通过解析 argparse 生成可视化设置表单、支持特定语法实现参数网格的批量任务生成、管理并行调度队列,以及在浏览器端提供 ANSI 彩色日志的实时流式输出和跨任务的指标聚合导出。
无需修改原生业务代码 · 无需注册账号 · 无需联网 · 所有流程均在本地执行
pip install pyruns
pyr train.py
💡 仅依赖 3 个包:
nicegui+pyyaml+psutil,安装后即用,不会给你的环境引入"重量级"框架。
💡 解决的工程痛点
痛点 1:超参搜索要靠手写 Bash 循环
没有 Pyruns 时——你需要写这种令人头痛的嵌套脚本:
for lr in 0.001 0.01 0.1; do
for bs in 32 64 128; do
for opt in adam sgd; do
python train.py --lr $lr --batch_size $bs --optimizer $opt \
> logs/lr${lr}_bs${bs}_${opt}.log 2>&1 &
done
done
done
wait
用 Pyruns——两行声明就等价于上面的 18 个嵌套组合:
lr: 0.001 | 0.01 | 0.1
batch_size: 32 | 64 | 128
optimizer: adam | sgd
点击 GENERATE → 自动创建 18 个隔离任务,每个任务有独立的配置快照和日志目录。
痛点 2:实验记录全靠人脑和 Excel
"上周跑的那组 lr=0.01 的实验,用的是哪个 batch_size 来着?结果保存在哪了?"
Pyruns 自动为每个任务保存完整的参数快照(config.yaml)、运行时间线、PID 记录、以及你随时可以追加的实验笔记。在 Manager 界面,你可以即时搜索、筛选、复用历史任务——再也不用翻文件夹或 grep 日志了。
痛点 3:多任务并发时日志混成一团
并发跑 6 个实验,终端输出全部交错在一起?Pyruns 将每个任务的标准输出完全隔离到独立日志文件,并在 Monitor 页面提供实时的 ANSI 彩色终端——包括 tqdm 进度条都能正确渲染。SSH 断开也不怕,任务在后台持续运行。
✨ 核心特性
| 特性 | 说明 |
|---|---|
| 🔌 多框架零侵入解析 | 从源码中提取 argparse 定义来渲染 Web UI 表单;亦支持直接基于 yaml 文件的配置;命令行模式可直接运行任意框架的脚本(包括 Hydra、Fire 等)。 |
| 🧮 参数网格展开 | 支持使用 | 进行笛卡尔积排列或 (|) 进行配对组合,用于生成批量参数配置集。 |
| ⚡ 独立任务队列 | 内部实现任务队列缓冲,可选 Thread/Process pool 型执行器控制并发规模。 |
| 📋 状态看板管理 | 对任务进行 Pending/Running/Failed/Completed 状态流转管理,支持对历史配置的搜索与复用。 |
| 🖥️ 流式彩色终端 | 增量返回终端输出并完整支持 ANSI 转义字符渲染(如 tqdm)。 |
| 📊 指标监控聚合 | 提供 pyruns.record() 回调,帮助在多组参数实验后导出 CSV/JSON 等合并报告。 |
| 📁 环境参数快照 | 在 _pyruns/ 下建立与脚本结构绑定的运行时目录,快照当前环境与参数,防干扰且支持软删除安全机制。 |
🎯 设计理念:Pyruns 不是一个重量级的实验平台(如 MLflow、W&B),而是一个开箱即用、轻量化的本地调参助手。它的目标是让你在不改变现有工作流的前提下,用最低的学习成本获得参数管理和实验追踪的便利。
🚀 启动方式
模式 1:基于 Argparse 的脚本接入
无需修改源码。Pyruns 通过 AST 分析器提取源码中 add_argument 的参数。
pyr train.py
这会在脚本所在目录下生成 _pyruns_/train/config_default.yaml,随后启动本地的 Web 服务(默认监听端口 8099)。
模式 2:基于 YAML 加载逻辑的接入
若您的源码直接通过读取外部 YAML 配置驱动并在代码内调用 pyruns.load():
# 首次运行:传入默认参数模板
pyr train.py my_config.yaml
此后,Pyruns 会接管参数调度及其相关环境变量:
pyr train.py
模式 3:CLI 命令行交互模式
如果你在无头服务器 (Headless Server) 上运行,或者更偏爱纯命令行操作,Pyruns 提供了一个与 Web UI 级别完全等同的 CLI 交互环境。
pyr cli train.py
这会自动构建和 Web UI 完全一样的工作区目录结构和配置,然后进入交互式的 REPL 终端:
Pyruns CLI (type 'help' for commands, 'exit' to quit)
pyruns> ls # 查看当前任务
pyruns> run 1 # 运行指定任务,并自动 stream 输出日志!
pyruns> status -i # 实时显示系统和 GPU 监控
任何通过 CLI 触发的操作和 Web UI 是 100% 数据互通和兼容的。
模式 4:命令行模式 / Args 模式(兼容任意框架)
Pyruns 的 Args 模式 可以用来管理任意框架的实验。你只需要在生成任务时使用 Args 视图,并在 run_script 中填写启动命令:
# 示例:管理 Hydra 实验
run_script: "python -m my_project.train"
args: |
model=vit
dataset=imagenet
training.lr=0.001
training.epochs=300
Pyruns 会将 args 字段的内容作为命令行参数直接追加到 run_script 后面执行。这意味着无论你的脚本使用 Hydra、Fire、Click 还是任何其他框架,只要它能通过命令行参数启动,你就可以利用 Pyruns 的批量生成和任务管理能力来管理它。
📝 实际上手示例
项目的 examples/ 目录下提供了可直接运行的完整示例脚本,分别对应两种接入模式。
示例 1:Argparse 原生支持(零改动接入)
对应目录:
examples/1_argparse_script/
下面是一个标准的 argparse 训练脚本,可以直接交给 Pyruns 接管——无需对原始代码做任何修改:
# examples/1_argparse_script/main.py
import pyruns
import argparse
import time
def main():
parser = argparse.ArgumentParser(description="A simple ML training script.")
parser.add_argument("--lr", type=float, default=0.001, help="Learning rate")
parser.add_argument("--epochs", type=int, default=10, help="Number of training epochs")
parser.add_argument("-b", "--batch_size", type=int, default=32, help="Batch size")
parser.add_argument("--optimizer", type=str, default="adam", choices=["adam", "sgd"])
args = parser.parse_args()
print(f"Hyperparameters: LR={args.lr}, Batch Size={args.batch_size}")
for epoch in range(1, args.epochs + 1):
time.sleep(0.5)
loss = 1.0 / (epoch * args.lr * 100)
print(f"Epoch {epoch}/{args.epochs} - Loss: {loss:.4f}")
# 可选:记录最终指标,脱离 Pyruns 环境时该调用被静默忽略
pyruns.record(last_loss=loss)
if __name__ == "__main__":
main()
使用方式:
# Pyruns 自动解析 argparse 参数并启动 Web UI
pyr main.py
Pyruns 通过 AST 静态分析自动提取 add_argument() 的所有定义(参数名、类型、默认值、help 文本),生成可编辑的 Web UI 表单。用户在界面修改参数后,Pyruns 会以命令行参数的形式将其传递给脚本——脚本本身的 parse_args() 逻辑完全不受影响。
示例 2:使用 pyruns.load() 加载 YAML 配置
对应目录:
examples/2_pyruns_config/
当训练脚本不使用命令行参数、而是直接读取 YAML 配置文件时,可以通过 pyruns.load() 完成接入。load() 返回的 ConfigNode 对象支持点号属性访问,嵌套结构会被自动递归封装:
# examples/2_pyruns_config/main1.py
import pyruns
import time
def main():
config = pyruns.load() # 自动绑定当前任务的 config.yaml
lr = config.lr
epochs = config.epochs
optimizer = config.optimizer
print(f"Hyperparameters: LR={lr}, Optimizer={optimizer}")
for epoch in range(1, epochs + 1):
time.sleep(0.5)
loss = 1.0 / (epoch * lr * 100)
print(f"Epoch {epoch}/{epochs} - Loss: {loss:.4f}")
if __name__ == "__main__":
main()
配套的默认配置文件 config1.yaml:
lr: 5e-3
epochs: 20
optimizer: sgd
batch_size: 64
dropout: 0.2
model: resnet50
使用方式:
# 首次运行:传入 YAML 模板,Pyruns 将其复制为 config_default.yaml
pyr main1.py config1.yaml
# 后续运行:无需再指定 YAML,Pyruns 自动使用已保存的模板
pyr main1.py
此外,pyruns.load() 也支持多层嵌套的 YAML 结构。以 config2.yaml 为例,项目、模型、训练三级分层的配置可以通过链式点号一路访问到底:
# config2.yaml — 三级嵌套结构
project:
name: "DeepSense_Alpha"
version: 1.2
output_dir: "./results"
model:
type: "Transformer"
layers: 12
dropout: 0.1
training:
hyperparams:
lr: 0.0005
epochs: 8
optimizer: "AdamW"
resources:
device: "cuda"
precision: "fp16"
gpu_config:
memory_frac: 0.8
在脚本中通过点号链式访问即可读取任意层级的值:
config = pyruns.load()
config.project.name # "DeepSense_Alpha"
config.training.hyperparams.lr # 0.0005
config.training.resources.device # "cuda"
🎯 界面模块
🔧 Generator — 简洁清晰的参数编辑器
在左侧提供清晰可见的结构化表单控制超参数修改,并支持声明化批量语法;右侧可实时预览将会并行生成的批量实验任务。通过(Pin)功能可以方便地标记核心参数。
📦 Manager — 便捷的历史任务记录与管理
核心的任务管理面板。能够极其方便地监控、搜索并管理所有生成的任务队列。支持勾选进行并发执行限制;点击进入任务卡片,可查阅其精准的参数快照 (config.yaml) 历史记录。
🔥 点击查看卡片内部详情弹窗特性
| 特性 | 视图预览 |
|---|---|
| 生命周期总览 重跑历史与 PIDs 记录 |
|
| 绝对隔离快照 独享的 config.yaml 映射 |
|
| 实验笔记记录 支持随时修改的实验副文本 |
|
| 环境变量溯源 完整还原任务启动时的全部系统变量 |
📈 Monitor — 实时查看与一键导出报告
将处于活跃状态的任务的标准输流出实时定向到浏览器终端。同时,监视到的任务运行指标(如 Loss、Accuracy 等),在此支持跨任务勾选,一键导出聚合比对报表。
🧪 批量生成语法
在 Generator 的代码域内支持特定的管道解析语法,用于描述性构建执行计划:
笛卡尔积组合 | — 全排列组装(如 3 × 2 = 6 个独立任务):
learning_rate: 0.001 | 0.01 | 0.1
batch_size: 32 | 64
一一配对映射 (|) — 等长对应(共 3 个独立任务):
seed: (1 | 2 | 3)
experiment_name: (exp_a | exp_b | exp_c)
支持数字序列区间(如:lr: 1:10:2)。详细结构规则见 批量构建语法说明。
📂 运行区结构原理
Pyruns 采用隔离持久化策略。针对单一入口脚本所生成的执行缓存符合以下文件树形规约:
your_project/
├── train.py
└── _pyruns_/
├── _pyruns_settings.yaml # 全局端口、并发数相关配制
└── train/ # 对应该脚本的独立命名空间
├── script_info.json # 记录脚本路径与环境依赖
├── config_default.yaml # UI 表单所需的参数初始骨架
└── tasks/
├── fast_tuning_[1-of-6]/
│ ├── task_info.json # 元数据状态机(存放执行PID、启停时间、监控数据等)
│ ├── config.yaml # 该任务启动时的确切参数配置切片
│ └── run_logs/
│ ├── run1.log # 主流终端输出
│ └── error.log # 非零状态码退出时的标准错误分离堆栈
└── .trash/ # Manager界面执行的非实质性软删除回收站
底层调用逻辑在执行队列发出 Run 信号时生效,执行器将 config.yaml 对应路径经由 __PYRUNS_CONFIG__ 环境变量置入被唤醒的子进程。
📖 补充文档
| 文档部分 | 说明 |
|---|---|
| 📗 安装部署与初次接入 | 环境说明与第一个示例运作 |
| 📘 批量语法细则 | 复杂网格规则与类型推断行为 |
| 💻 命令行 CLI 交互控制 | 在无头服务器/纯终端使用 REPL 环境管理全部流程的操作详解 |
| 📕 界面高级操作与控制 | Manager执行限制细节及报表数据的导出等 |
| 📙 配置流转与沙盒说明 | Node树层级、优先读取顺位判定 |
| 📓 API 接口文档 | 深入代码端的 read() / load() 及 record() 功能介绍 |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyruns-0.1.2.tar.gz.
File metadata
- Download URL: pyruns-0.1.2.tar.gz
- Upload date:
- Size: 130.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3d55f93d256e761ef0c0220080db4a5854cd7956ab93095264b862f09c55517
|
|
| MD5 |
623fbee139c8ceb8474b14abe53d70b8
|
|
| BLAKE2b-256 |
828822912eb7df5630f6ef651f73d9b22fbff14c69986e8e0123303bbb909aa5
|
File details
Details for the file pyruns-0.1.2-py3-none-any.whl.
File metadata
- Download URL: pyruns-0.1.2-py3-none-any.whl
- Upload date:
- Size: 126.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
876598180d1b71f506bd029cab474aa96ca1b651dc989723514798028207beba
|
|
| MD5 |
dcc117403bcf857f4a84e2ec862dd86b
|
|
| BLAKE2b-256 |
e8765ffe9677537e06624e3b6644aec7cefdeebbfc49f43b052315b33f304632
|