mac + server 完全一致的实验模板

科研 / 工程可复现标准组织,适合长期查询、复制、扩展。


mac + server 完全一致的实验模板(统一运行规范)

目标

使用同一套代码结构、同一条 .sh 命令,在 mac 本地 / 远程服务器 / 不同时间 / 不同执行者
无歧义、可复现地运行实验


一、核心设计原则(必须遵守)

✅ 原则 1:.sh 是唯一实验入口

  • ❌ 禁止直接 python xxx.py
  • ✅ 只能通过 bash scripts/run_xxx.sh

✅ 原则 2:mac 与 server 使用同一套命令

  • 不区分 run_local.sh / run_server.sh
  • 环境差异 仅通过环境变量体现

✅ 原则 3:路径统一,相对项目根目录

  • /Users/...
  • /home/...
  • $(pwd) / PROJECT_ROOT

✅ 原则 4:参数显式、可记录

  • 所有超参必须写在 .sh
  • 日志中必须包含 Git commit + 参数

✅ 原则 5:Token 永不进入代码

  • 只通过 export XXX_TOKEN=...
  • .py 中仅 os.getenv()

二、标准目录结构(mac / server 100% 一致)

text 复制代码
project_name/
├── README.md
├── RUNBOOK.md              # 实验行动日志(强烈推荐)
├── requirements.txt
├── .gitignore
│
├── data/                   # 数据(或软链接)
│   ├── raw/
│   └── processed/
│
├── src/                    # 纯 Python 逻辑(无环境依赖)
│   ├── train.py
│   ├── eval.py
│   ├── model/
│   └── utils/
│
├── scripts/                # 唯一执行入口
│   ├── env.sh              # 统一环境定义(核心)
│   ├── run_train.sh
│   └── run_eval.sh
│
├── configs/                # 可选(YAML / JSON)
│   └── default.yaml
│
├── runs/                   # 实验输出(git ignore)
│   └── exp_xxx/
│
└── logs/                   # 日志(git ignore)

设计思想

  • src/:只关心算法
  • scripts/:决定怎么跑
  • runs/ / logs/:结果与证据

三、关键脚本模板


1️⃣ scripts/env.sh(mac + server 统一核心)

bash 复制代码
#!/bin/bash
set -e

# =============================
# Project root
# =============================
export PROJECT_ROOT=$(pwd)

# =============================
# Python / CUDA
# =============================
export PYTHONPATH=$PROJECT_ROOT
export CUDA_VISIBLE_DEVICES=${CUDA_VISIBLE_DEVICES:-0}

# =============================
# Tokens (from environment)
# =============================
export OPENAI_API_KEY=${OPENAI_API_KEY:-""}
export HF_TOKEN=${HF_TOKEN:-""}

# =============================
# Reproducibility
# =============================
export SEED=42

# =============================
# Run identification
# =============================
GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "nogit")
export EXP_TAG=${EXP_TAG:-"debug"}
export RUN_ID="${EXP_TAG}_${GIT_COMMIT}_$(date +%Y%m%d_%H%M%S)"

echo "[INFO] PROJECT_ROOT = $PROJECT_ROOT"
echo "[INFO] CUDA_VISIBLE_DEVICES = $CUDA_VISIBLE_DEVICES"
echo "[INFO] GIT_COMMIT = $GIT_COMMIT"
echo "[INFO] RUN_ID = $RUN_ID"

2️⃣ scripts/run_train.sh(唯一训练入口)

bash 复制代码
#!/bin/bash
set -e

# =============================
# Load unified environment
# =============================
source scripts/env.sh

# =============================
# Paths
# =============================
DATA_DIR=$PROJECT_ROOT/data/processed
OUT_DIR=$PROJECT_ROOT/runs/$RUN_ID
LOG_DIR=$PROJECT_ROOT/logs

mkdir -p $OUT_DIR
mkdir -p $LOG_DIR

# =============================
# Run training
# =============================
python src/train.py \
  --data_dir $DATA_DIR \
  --output_dir $OUT_DIR \
  --seed $SEED \
  --epochs 50 \
  --batch_size 64 \
  --lr 1e-3 \
  2>&1 | tee $LOG_DIR/train_$RUN_ID.log

3️⃣ src/train.py(算法文件示例)

python 复制代码
import argparse
import os
import random
import numpy as np

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--data_dir", required=True)
    parser.add_argument("--output_dir", required=True)
    parser.add_argument("--seed", type=int, default=42)
    parser.add_argument("--epochs", type=int, default=50)
    parser.add_argument("--batch_size", type=int, default=64)
    parser.add_argument("--lr", type=float, default=1e-3)
    return parser.parse_args()

def set_seed(seed):
    random.seed(seed)
    np.random.seed(seed)

if __name__ == "__main__":
    args = parse_args()
    set_seed(args.seed)

    os.makedirs(args.output_dir, exist_ok=True)

    print("=== Training Config ===")
    for k, v in vars(args).items():
        print(f"{k}: {v}")

    # TODO: training logic

四、运行方式(mac / server 完全一致)

✅ mac 本地(测试 / CPU)

bash 复制代码
cd project_name
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

export EXP_TAG=local_test
bash scripts/run_train.sh

✅ 远程服务器(GPU / 正式实验)

bash 复制代码
ssh user@server
cd project_name

conda activate exp
export CUDA_VISIBLE_DEVICES=0
export EXP_TAG=main_exp
export OPENAI_API_KEY=xxxx

nohup bash scripts/run_train.sh > logs/nohup.out 2>&1 &

⚠️ 命令完全一致,仅多了:

  • nohup
  • GPU / token 环境变量

五、实验命名与可回溯性

实验输出自动生成如下结构:

text 复制代码
runs/
└── main_exp_a1b2c3_20260122_153012/
logs/
└── train_main_exp_a1b2c3_20260122_153012.log

日志中必须包含:

  • Git commit
  • 超参数
  • 时间戳
  • EXP_TAG

六、RUNBOOK(实验行动日志模板)

建议保存为 RUNBOOK.md

markdown 复制代码
# Experiment Runbook

## Project
- Name:
- Objective:

## Environment
- Machine: mac / server
- Python:
- CUDA_VISIBLE_DEVICES:

## Code
- Git commit:

## Data
- raw:
- processed:

## Run Command
```bash
export EXP_TAG=
export CUDA_VISIBLE_DEVICES=
bash scripts/run_train.sh

Output

  • runs/:
  • logs/:

Notes

复制代码
---

## 七、适用场景说明

本模板适用于:
- 多模态故障诊断
- 深度学习 / 大模型训练
- mac + GPU server 混合开发
- 论文级可复现研究
- 工程化长期项目

---

## 八、下一步可扩展方向(可选)

- 多实验 sweep(for-loop / grid)
- 自动保存 config.yaml
- 评估 / 推理独立脚本
- 论文 Reproducibility 附录自动生成

---

> **一句话总结**  
> **这套模板的价值不在"能跑",而在"任何时候都知道你是怎么跑的"。**

如果你愿意,下一步我可以直接**按你现有项目结构帮你重构到这一模板中**,只需要你贴出当前目录树即可。
相关推荐
pe7er21 小时前
macOS 应用无法打开(权限问题)解决方案
macos·mac
harmful_sheep3 天前
mac生效的终端查看
macos
iOS门童4 天前
macOS 应用"已损坏"无法打开?一文搞懂 Gatekeeper 与解决方案
macos
NPE~4 天前
[工具分享]Maccy —— 优雅的 macOS 剪贴板历史管理工具
macos·教程·工具·实用工具
差不多程序员4 天前
Mac安装OpenClaw-cn保姆级教程
macos
dzl843944 天前
mac 安装python
开发语言·python·macos
Bruce_Liuxiaowei4 天前
在 macOS 上通过 Docker 本地安装 OpenClaw 完整教程
macos·docker·容器·openclaw
阿捏利4 天前
详解Mach-O(十五)Mach-O __DATA_CONST
macos·ios·c/c++·mach-o
ShikiSuen4 天前
macOS 的 CpLk 中英切换卡顿的元凶在 InputMethodKit 本身
macos
xiayutian_c4 天前
如虎添翼-MacOS
macos