Skip to content

快速开始 ​

本页从安装开始,分别完成一个 shell 任务和一个 Python 配置任务,并说明如何查询、取消、导出和打开 Web UI。

命令示例以 Linux/Bash 为主;其他平台请按实际 Shell 调整引用、变量、续行、路径和标准输入 写法,详见 pyr exec --help 或跨平台差异。

1. 安装与确认入口 ​

bash
pip install pyruns
pyr --version
pyr --help
pyruns --version
pyruns --help
pyr exec --help

Pyruns 同时安装 pyr 与 pyruns 两个完全等价的正式命令。本文使用更短的 pyr;任何示例都可以原样换成 pyruns。裸命令、pyr help 与 --help 列出全部命令及用途,参数、示例和注意事项统一使用 pyr COMMAND --help 查看。这些帮助命令都不会创建工作区或启动 Web 服务。

当你不确定应该使用 -c、--stdin、-e 还是 --env-file 时,直接运行 pyr exec --help;它按常见场景给出选择规则和后续查看日志、等待、重跑的命令。

2. 第一个 shell 任务 ​

进入一个项目目录:

bash
cd my-project
pyr exec -n smoke -c "python -V"

exec 会自动创建 shell workspace、任务和第一次运行记录:

text
my-project/
└── _pyruns_/
    ├── _pyruns_settings.yaml
    └── _shell_/
        ├── script_info.json
        └── tasks/

这里使用 -n smoke 是因为后续命令要精确引用 smoke。临时运行时不必手动取名; 省略名称会生成 task_YYYY-MM-DD_HH-MM-SS,-nt PREFIX 则生成带语义前缀的时间戳名称:

bash
pyr exec -c "python -V"
pyr exec -nt smoke -c "python -V"  # smoke_YYYY-MM-DD_HH-MM-SS

-n NAME 是精确名称,-nt PREFIX 是自动名称,两者不能同时使用。同一秒发生名称冲突时, Pyruns 仍会使用现有的安全去重后缀,避免覆盖任务。

目标程序的参数放在 -c "完整命令" 的引号内,Pyruns 选项放在字符串外;多行脚本用 --stdin 保存正文。

只预览计划、不创建 workspace/task 也不运行命令:

bash
pyr exec --dry-run -n smoke -c "python -V"
pyr exec --dry-run -n smoke --json -c "python -V"

任务结束后查询:

bash
pyr ls
pyr show smoke
pyr log smoke

这里只有一个 workspace,因此可以省略 -w shell;多 workspace 项目再显式选择。

任务目录类似:

text
_pyruns_/_shell_/tasks/smoke/
├── task_info.json
├── config.sh | config.ps1 | config.cmd
└── run_logs/run1.log

3. 长任务与后台运行 ​

默认 exec 会跟随日志并把任务成功或失败反映到退出码。长任务可使用 --detach:

bash
pyr exec -n train -d -c "python train.py --epochs 100"

runner 接受任务后,命令立即返回;关闭调用终端不会终止任务。Windows 上 runner 和任务进程不会弹出新的控制台窗口。

随后可以在任意新终端中执行:

bash
pyr status
pyr show train
pyr log train -f
pyr wait train --timeout 3600

取消活动任务:

bash
pyr stop train

取消请求会送到真正拥有该任务的 runner,而不是只修改显示状态。

等待 GPU 空闲后自动运行 ​

GPU 任务可同时使用 -d 和 --gpu-wait,在后台排队,达标后自动执行:

bash
pyr exec -n gpu-train -d --gpu-wait 2-20-70-15-2 -c "python train.py"
# 多行脚本也支持 GPU 等待,并保存完整正文
pyr exec -nt gpu-pipeline -d --gpu-wait 1-8-70-15-2 --stdin < pipeline.sh

规则依次为 卡数-每卡空闲 GiB-最低 GPU 空闲率 %-连续满足秒数-最长等待小时,五项必须完整填写。 2-20-70-15-2 要求两张卡同时各自空闲至少 20 GiB、空闲率至少 70%,连续满足 15 秒后启动,最多排队 2 小时;空闲率是 100 - GPU 利用率。超时只限制排队时间。

等待输出按这五项显示当前值、要求及 ready / blocked 原因。利用率 93% 等于空闲率 7%; 所需的每张卡都必须达标;显存或空闲率不达标、指标缺失或采样中断时,其连续达标时间会重置。 指标缺失、GPU 不可见或被本工作区其他任务预留时,也会说明原因。

CLI 规则仅本次运行生效,再次 run 时需要重新传入;不传 --gpu-wait 就不进行 GPU 等待。 UI 的 Runtime 开关只影响之后从 UI 提交的任务。 用 pyr show gpu-train 查看本次规则和等待状态,pyr metrics 查看当前 GPU 指标。 指定卡、单位和其他细节见 GPU 等待规则 或 pyr exec --help。

如果要让后续从 Web UI 提交的任务持续使用 GPU wait scheduler,运行 pyr ui 或 pyr ui shell, 在 Runtime -> GPU 打开并保存 GPU scheduling。UI 的 GPUs required、空闲显存、GPU 空闲率、 稳定时间和最长等待与 CLI 的五项规则含义一致;UI 设置持续生效,CLI 的 --gpu-wait 仍只对当前一次运行生效。

4. 使用 -c 执行完整命令 ​

普通程序和脚本文件都使用 -c "完整命令"。脚本需要的解释器写在命令内, Pyruns 记录日志、运行时长和退出码:

bash
pyr exec -n eval -c 'python eval.py --checkpoint "best model.pt"'
pyr exec -n preprocess -c 'bash ./scripts/preprocess.sh "dataset A" --fast'

-c / --command 也支持管道、重定向、变量展开、通配符和 && 等工作区 Shell 语法。 将整段命令引用为一个参数,Pyruns 选项可以放在 -c "命令" 前面或后面。 长命令和多行脚本使用 --stdin 保存完整正文。Shell 表达式示例:

bash
pyr exec -n report -c "python eval.py > metrics.txt"
pyr exec -n pipeline -c "python preprocess.py && python train.py | tee train.log"

所有平台都使用相同规则:-c 接收完整命令字符串,--stdin 接收完整脚本正文。例如在 Bash 中输出彩色日志:

bash
pyr exec -c 'printf "\033[31mred\033[0m\n\033[32mgreen\033[0m\n"'

Shell task 使用跨平台伪终端保留颜色:Linux/macOS 使用系统 PTY,Windows 在已有控制台时使用原生 ConPTY。没有已附着的 Windows 控制台时,会回退到隐藏的 stdout/stderr 管道,避免弹出控制台窗口,此时颜色可能丢失。伪终端捕获的日志保留 SGR 颜色,但过滤清屏、光标定位和窗口标题等控制序列。

少量环境变量只需写一次 -e,再用 -c 提供完整命令:

bash
pyr exec -n gpu0 -e CUDA_VISIBLE_DEVICES=0 TOKENIZERS_PARALLELISM=false SEED=42 -c "python train.py"

-e / --env 可以按变量组重复使用。Pyruns 已自动为子进程设置 PYTHONUNBUFFERED=1、PYTHONIOENCODING=utf-8 和 PYTHONUTF8=1。

变量较多时写入 UTF-8 env 文件:

dotenv
# .env.train
CUDA_VISIBLE_DEVICES=0
TOKENIZERS_PARALLELISM=false
bash
pyr exec -n gpu0 --env-file .env.train -e SEED=42 -c "python train.py"

--env-file 可重复:后面的文件覆盖前面的文件,命令行 -e 再覆盖文件值。文件只读取空行、整行 # 注释和 KEY=VALUE,不做 shell 插值。变量会明文保存到任务元数据,所以不要用于密钥。

在 POSIX shell 中也可写 CUDA_VISIBLE_DEVICES=0 pyr exec ...,当前运行会继承该变量;但它不会被任务保存,后续从别的终端、Web UI 或 pyr run 重跑时不保证相同。需要可复现时仍应使用 -e 或 --env-file。

5. 第一个 Python script workspace ​

假设 train.py 使用 argparse:

python
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--lr", type=float, default=0.001)
parser.add_argument("--epochs", type=int, default=10)
args = parser.parse_args()

print(f"lr={args.lr}, epochs={args.epochs}")

初始化:

bash
pyr init train.py

这会创建 _pyruns_/train/,并准备 config_default.yaml。

初始化通过静态解析读取参数,支持默认值和 choices 中的字面量 * / ** 展开。展开来源依赖变量或函数调用时,无法确定的值保留为 null,请在配置中填写。

创建一份配置,例如 configs/quick.yaml:

yaml
lr: 0.001
epochs: 2

创建并运行:

bash
pyr -w train add configs/quick.yaml -n quick
pyr -w train run quick

也可以合并为一次操作:

bash
pyr -w train run --config configs/quick.yaml -n quick
pyr -w train run --config configs/quick.yaml -n quick --dry-run

6. pyruns.load() 脚本 ​

如果脚本直接读取 YAML:

python
import pyruns

cfg = pyruns.load()
print(cfg.training.lr)

第一次初始化时提供模板:

bash
pyr init train.py --config configs/default.yaml

后续仍使用 add 和 run:

bash
pyr -w train add configs/sweep.yaml -n sweep
pyr -w train run sweep_1-of-4 sweep_2-of-4 -j 2

任务名必须精确填写;Pyruns 不接受列表序号或模糊名称。

7. Batch 配置 ​

Pyruns 可以把 YAML 中的 batch 表达式展开成多个任务。示例:

yaml
lr: 0.0001 | 0.001
seed: 1 | 2
epochs: 10
bash
pyr -w train add configs/sweep.yaml -n sweep
pyr -w train ls sweep
pyr -w train run sweep_1-of-4 sweep_2-of-4 -j 2

完整语法见 批量配置语法。

8. 多工作区项目 ​

Pyruns 从当前目录向父目录查找最近的 _pyruns_:

  • 只有一个 workspace:自动选择。
  • 多个 workspace:必须使用 -w。
  • 没有 workspace:其他任务命令提示先 pyr init。
  • exec 不向上复用 shell workspace,始终在当前目录自动创建或使用 _pyruns_/_shell_。
bash
pyr -w shell ls
pyr -w train ls
pyr -w ./train.py status
pyr -w ./_pyruns_/train show quick
pyr -w ./_pyruns_/train show quick@2
pyr -w ./_pyruns_/train show quick --run 2

从另一个目录操作项目可以使用 -C:

bash
pyr -C /home/user/work/my-project -w shell status

-C、-w 等项目上下文参数放在子命令之前;--json 只能放在明确支持它的子命令后。

9. 稳定 JSON 输出 ​

所有 --json 结果都是严格 JSON 对象,顶层带有 "schema_version": 1。 非有限数字不会被输出为非标准的 NaN 或 Infinity。

脚本、CI 和 AI agent 应优先读取 JSON,而不是解析表格:

bash
pyr -w shell ls --json
pyr -w shell status --json
pyr -w shell show smoke --json
pyr -w shell show smoke@2 --json
pyr -w shell show smoke --run 2 --json
pyr -w shell log smoke --path --json
pyr -w shell log smoke@2 --path --json
pyr config list --json
pyr metrics --json

log 默认原样输出日志,因此只有 log --path 支持 --json。

退出码:

text
0    命令和等待的任务全部成功
1    工作区、目标、运行时或任务失败
2    命令行用法错误
130  等待或跟随日志时被中断

10. 任务生命周期 ​

bash
pyr -w train mv quick quick-lr1e3
pyr -w train pin quick-lr1e3
pyr -w train pin quick-lr1e3 --off
pyr -w train rm quick-lr1e3
pyr -w train ls --trash
pyr -w train restore quick-lr1e3

rm 不询问确认并立即执行,但只是可恢复的软删除。

11. 导出与配置 ​

导出默认写 stdout:

bash
pyr -w train export -f csv
pyr -w train export quick -f json
pyr -w train export -s completed -o results.csv

管理项目配置:

bash
pyr config list
pyr config get monitor_scrollback
pyr config set monitor_scrollback 200000
pyr config unset monitor_scrollback
pyr config path

批量运行的并发数在每次 run 时通过 -j/--jobs 明确选择,不会藏在项目配置里。

12. 显式打开 Web UI ​

CLI 是默认控制面;需要可视化浏览时显式启动:

bash
pyr ui                                  # workspace launcher
pyr ui train.py                         # script workspace
pyr ui train.py --config config.yaml    # 导入模板
pyr ui shell                            # shell workspace
pyr ui shell --no-browser               # headless server
pyr dev train.py                        # 开发热更新

每次 UI 启动都会打印一个带随机访问令牌的本机 URL。浏览器首次打开后会改用 持久的 HttpOnly 会话 cookie,并从地址栏移除令牌。会话在使用时续期,同一主机、 端口和工作区的正常更新或重启不会要求重新认证;清除浏览器数据或本地 ~/.pyruns/sessions 状态后才需要重新打开最新 URL。--no-browser 场景需要复制完整 URL,且不要分享给其他用户。UI 只面向本机使用,不是远程多用户服务。

Web UI 与 CLI 共用 _pyruns_ 状态。可以用 CLI 提交,再在 UI 中观察,或者反过来查询和取消。

13. 从源码开发 ​

bash
git clone https://github.com/LthreeC/pyruns.git
cd pyruns
python -m pip install -e .
pyr --help

前端开发与构建要求 Node.js 20 或更高版本:

bash
npm --prefix frontend install
npm --prefix frontend run dev
npm --prefix frontend run build

下一步 ​