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 附录自动生成

---

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

如果你愿意,下一步我可以直接**按你现有项目结构帮你重构到这一模板中**,只需要你贴出当前目录树即可。
相关推荐
TESmart碲视2 小时前
KVM切换器支持高刷新率游戏吗?
游戏·macos·计算机外设·kvm切换器·双屏kvm切换器
爱喝矿泉水的猛男2 小时前
哪些鼠标不支持Mac mouse fix呢?
macos·计算机外设
ASKED_20191 天前
macOS 使用 Codex CLI 登录报错 403 的问题分析与解决方案(Issue #2414)
macos·issue
roo_11 天前
JAVA学习-MAC搭建java环境和spring boot搭建
java·学习·macos
Digitally1 天前
如何在 Mac 上进行屏幕录制(分步教程)
macos
2501_916008891 天前
在不越狱前提下导出 iOS 应用文件的过程,访问应用沙盒目录,获取真实数据
android·macos·ios·小程序·uni-app·cocoa·iphone
vchao_1 天前
Mac升级系统后反复重启问题
macos·反复重启
TheNextByte11 天前
如何在Mac上获取Android消息
android·macos
虹少侠1 天前
基于 WebKit 构建 macOS 多浮窗视频播放的技术实践(含完整产品落地)
前端·macos·swift·webkit