cwenzi/neuroflow-cpp
1
1#!/bin/bash2# ═══════════════════════════════════════════════════════════════3# NeuroFlow — 阿里天池 DSW CUDA 一键部署/训练脚本4# 适用: DSW GPU 实例, A10 / V100 / 其他 sm_80+ 显卡5# 用法: bash deploy_dsw.sh6# ═══════════════════════════════════════════════════════════════7 8set -euo pipefail9 10REPO_DIR="neuroflow-C++"11BUILD_DIR="build_cuda"12GIT_REPO="https://github.com/chenzhiwenhphp12-afk/neuroflow-model.git"13 14echo "╔══════════════════════════════════════════════════╗"15echo "║ NeuroFlow DSW 部署 + 蒸馏训练脚本 ║"16echo "╚══════════════════════════════════════════════════╝"17 18# ── 0. 检查 GPU ──19echo ""20echo "🔍 [0/7] 检查 GPU / CUDA..."21if ! command -v nvidia-smi &>/dev/null; then22 echo "❌ nvidia-smi 未找到,请确认已开启 GPU 实例"23 exit 124fi25nvidia-smi26echo ""27 28if ! command -v nvcc &>/dev/null; then29 echo "⚠️ nvcc 未找到。DSW 镜像里 CUDA 通常装在 /usr/local/cuda"30 export CUDA_HOME=/usr/local/cuda31 export PATH="$CUDA_HOME/bin:$PATH"32 if ! command -v nvcc &>/dev/null; then33 echo "❌ 仍未找到 nvcc,请确认 CUDA Toolkit 已安装"34 exit 135 fi36fi37nvcc --version | grep "release"38echo "✅ CUDA 就绪"39echo ""40 41# ── 1. 安装系统依赖 ──42echo "📦 [1/7] 安装编译依赖..."43apt-get update -qq44apt-get install -y -qq cmake build-essential python3 python3-pip git 2>/dev/null || true45echo "✅ 依赖安装完成"46echo ""47 48# ── 2. 获取代码 ──49echo "📥 [2/7] 获取 NeuroFlow 源码..."50if [ -d "$REPO_DIR" ]; then51 echo " 检测到已有目录,执行 git pull..."52 cd "$REPO_DIR"53 git pull || true54 cd ..55else56 echo " 正在克隆: $GIT_REPO"57 git clone "$GIT_REPO" "$REPO_DIR"58fi59cd "$REPO_DIR"60echo "✅ 代码就绪: $(pwd)"61echo ""62 63# ── 3. 数据格式转换 ──64echo "📝 [3/7] 准备训练数据..."65DEEPSEEK_JSONL="${DEEPSEEK_JSONL:-}"66DATA_TXT="data/distill_train.txt"67 68if [ ! -f "$DATA_TXT" ]; then69 mkdir -p data70 71 if [ -n "$DEEPSEEK_JSONL" ] && [ -f "$DEEPSEEK_JSONL" ]; then72 echo " 使用 DeepSeek 蒸馏数据: $DEEPSEEK_JSONL"73 python3 scripts/preprocess_distill.py "$DEEPSEEK_JSONL" "$DATA_TXT" 24000074 else75 echo " ⚠️ 未找到蒸馏数据,生成 5000 条测试样本..."76 python3 -c "77samples = []78for i in range(5000):79 samples.append(f'这是第{i}条训练数据,用于NeuroFlow模型测试。')80with open('$DATA_TXT', 'w', encoding='utf-8') as f:81 f.write('\n'.join(samples))82print(f'已生成 {len(samples)} 条样本 -> $DATA_TXT')83"84 fi85else86 echo " 训练数据已存在: $DATA_TXT"87fi88ls -lh "$DATA_TXT"89echo ""90 91# ── 4. 修复 CMake CUDA 编译 ──92echo "🔧 [4/7] 修复 CMake CUDA 编译配置..."93# 本项目要求所有 src/*.cpp 都以 CUDA 语言编译,否则训练回退 CPU94# 将非 CUDA 源文件强制设为 CUDA 语言95CMAKE_FILE="CMakeLists.txt"96if [ -f "$CMAKE_FILE" ]; then97 # 在 set_source_files_properties(src/cuda_context.cpp ...) 后插入全量 CUDA 映射98 if ! grep -q "set_source_files_properties(src/tensor_ops.cpp" "$CMAKE_FILE"; then99 echo " 为所有 src/*.cpp 添加 CUDA 编译属性..."100 python3 -c "101import re102p = '$CMAKE_FILE'103with open(p, 'r', encoding='utf-8') as f:104 c = f.read()105anchor = 'set_source_files_properties(src/cuda_context.cpp PROPERTIES LANGUAGE CUDA)'106if anchor in c and 'NEUROFLOW_ALL_CUDA_SOURCES' not in c:107 srcs = '''src/train_v2.cpp src/infer_v2.cpp src/tensor.cpp src/model.cpp src/weight_io.cpp108src/tokenizer.cpp src/sampling.cpp src/causal_lm.cpp src/tensor_ops.cpp src/generative_model.cpp109src/rope.cpp src/swiglu.cpp src/rms_norm.cpp src/adamw.cpp src/scheduler.cpp src/train_lm.cpp110src/grad_scaler.cpp src/cuda_context.cpp'''.split()111 block = '\n'.join([f'set_source_files_properties({s} PROPERTIES LANGUAGE CUDA)' for s in srcs])112 c = c.replace(anchor, anchor + '\n' + block + '\n', 1)113 with open(p, 'w', encoding='utf-8') as f:114 f.write(c)115 print(' CMake 已更新')116else:117 print(' 跳过 (已配置或缺少锚点)')118"119 fi120else121 echo "❌ 未找到 $CMAKE_FILE"122 exit 1123fi124echo ""125 126# ── 5. 编译 CUDA 版本 ──127echo "🔨 [5/7] 编译 NeuroFlow (CUDA 模式)..."128rm -rf "$BUILD_DIR"129mkdir -p "$BUILD_DIR"130cd "$BUILD_DIR"131 132cmake .. \133 -DNEUROFLOW_USE_CUDA=ON \134 -DNEUROFLOW_USE_BLAS=OFF \135 -DNEUROFLOW_USE_AVX2=OFF \136 -DCMAKE_BUILD_TYPE=Release137 138cmake --build . -j"$(nproc)"139echo "✅ 编译完成"140echo ""141 142# ── 6. 小规模验证 ──143echo "🧪 [6/7] 小规模验证 (5 epochs)..."144cd "$REPO_DIR"145./"$BUILD_DIR"/neuroflow_train_v2 \146 --config configs/config_distill.json \147 --data "$DATA_TXT" \148 --output output_dsw_verify \149 --epochs 5 \150 --batch-size 16 \151 --lr 0.001 \152 --use-cuda \153 --adam \154 --log-interval 10 \155 --save-interval 100 || {156 echo "⚠️ 验证失败,查看上方错误"157 exit 1158 }159echo "✅ 验证完成"160echo ""161 162# ── 7. 正式训练 (蒸馏) ──163echo "🚀 [7/7] 开始正式蒸馏训练..."164echo "════════════════════════════════════════════════════"165echo " 配置: configs/config.json (128K vocab)"166echo " 数据: $DATA_TXT"167echo " 输出: output_dsw_distill"168echo "════════════════════════════════════════════════════"169 170./"$BUILD_DIR"/neuroflow_train_v2 \171 --config configs/config.json \172 --data "$DATA_TXT" \173 --output output_dsw_distill \174 --epochs 10 \175 --batch-size 64 \176 --lr 0.0003 \177 --grad-accum 4 \178 --use-cuda \179 --adam \180 --log-interval 10 \181 --save-interval 2000 \182 --replay-buffer 10000 \183 --replay-ratio 0.25184 185echo ""186echo "╔══════════════════════════════════════════════════╗"187echo "║ 训练完成! ║"188echo "╚══════════════════════════════════════════════════╝"189echo ""190echo "📁 模型目录: output_dsw_distill/"191ls -lh output_dsw_distill/ 2>/dev/null || true192echo ""193echo "🔜 续训命令:"194echo " ./$BUILD_DIR/neuroflow_train_v2 \\"195echo " --config configs/config.json \\"196echo " --data $DATA_TXT \\"197echo " --output output_dsw_distill \\"198echo " --resume output_dsw_distill/model_final.nfv1 \\"199echo " --epochs 20 \\"200echo " --batch-size 64 \\"201echo " --lr 0.0003 \\"202echo " --grad-accum 4 \\"203echo " --use-cuda --adam"204 