Upload src/bluscriptCP.cpp with huggingface_hub
Browse files- src/bluscriptCP.cpp +53 -5
src/bluscriptCP.cpp
CHANGED
|
@@ -83,6 +83,7 @@
|
|
| 83 |
#include "DataParallel.hpp" // DataParallel, DDP_Options
|
| 84 |
#include "dist/zero/include/ShardedOptimizer.h" // owt::zero::ShardedOptimizer (ZeRO-1)
|
| 85 |
#include "dist/zero/include/SymmetricShardedOptimizer.h" // ZeRO-1 v2 (reduce-scatter/all-gather)
|
|
|
|
| 86 |
#include "dist/zero/include/ZeroOptimizerBase.h" // common surface: v1/v2 interchangeable
|
| 87 |
|
| 88 |
// Context parallelism
|
|
@@ -148,8 +149,9 @@ struct ModelConfig {
|
|
| 148 |
float grad_clip = 1.0f;
|
| 149 |
float weight_decay = 0.1f;
|
| 150 |
|
| 151 |
-
float max_lr = 6e-4f;
|
| 152 |
-
float min_lr = 6e-5f; // 10% of max_lr
|
|
|
|
| 153 |
int warmup_steps = 91;
|
| 154 |
// CP_BF16=1 makes the Linears (wQ/wK/wV/wO, gate_up/down, lm_head matmul)
|
| 155 |
// bf16 with fp32 norms, fp32 residual stream and fp32 logits -- the scheme
|
|
@@ -982,6 +984,20 @@ int main(int argc, char** argv) {
|
|
| 982 |
cfg.max_steps = static_cast<int>(env_i64("CP_MAX_STEPS", cfg.max_steps));
|
| 983 |
cfg.warmup_steps = static_cast<int>(env_i64("CP_WARMUP", cfg.warmup_steps));
|
| 984 |
cfg.stable_steps = static_cast<int>(env_i64("CP_STABLE", cfg.stable_steps));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 985 |
cfg.bf16 = env_i64("CP_BF16", cfg.bf16 ? 1 : 0) != 0;
|
| 986 |
cfg.bf16_mask = static_cast<int>(env_i64("CP_BF16_MASK", cfg.bf16_mask));
|
| 987 |
// Defaults ON when bf16 is requested at world_size>1, because DDP is broken
|
|
@@ -1716,8 +1732,34 @@ int main(int argc, char** argv) {
|
|
| 1716 |
// direction. Reduce in fp32 when that is suspected.
|
| 1717 |
zcfg.reduce_dtype = owt::zero::ReduceDtype::FP32;
|
| 1718 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1719 |
for (auto& kv : params_by_dtype) {
|
| 1720 |
-
if (cfg.
|
|
|
|
|
|
|
| 1721 |
zopts.push_back(std::make_unique<owt::zero::SymmetricShardedOptimizer>(kv.second, pg, zcfg));
|
| 1722 |
else
|
| 1723 |
zopts.push_back(std::make_unique<owt::zero::ShardedOptimizer>(kv.second, pg, zcfg));
|
|
@@ -1725,8 +1767,14 @@ int main(int argc, char** argv) {
|
|
| 1725 |
zgroup_label.push_back(OwnTensor::get_dtype_name(kv.first) + "/" + std::to_string(n));
|
| 1726 |
}
|
| 1727 |
if (is_master) {
|
| 1728 |
-
|
| 1729 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1730 |
<< " groups=" << zopts.size();
|
| 1731 |
for (auto& g : zgroup_label) std::cout << " [" << g << "]";
|
| 1732 |
std::cout << "\n[ZeRO-1] DataParallel is DISABLED (both would double-reduce)"
|
|
|
|
| 83 |
#include "DataParallel.hpp" // DataParallel, DDP_Options
|
| 84 |
#include "dist/zero/include/ShardedOptimizer.h" // owt::zero::ShardedOptimizer (ZeRO-1)
|
| 85 |
#include "dist/zero/include/SymmetricShardedOptimizer.h" // ZeRO-1 v2 (reduce-scatter/all-gather)
|
| 86 |
+
#include "dist/zero/include/ShardedMuon.h" // owt::zero::ShardedMuon (ZeRO-1 over whole tensors)
|
| 87 |
#include "dist/zero/include/ZeroOptimizerBase.h" // common surface: v1/v2 interchangeable
|
| 88 |
|
| 89 |
// Context parallelism
|
|
|
|
| 149 |
float grad_clip = 1.0f;
|
| 150 |
float weight_decay = 0.1f;
|
| 151 |
|
| 152 |
+
float max_lr = 6e-4f; // CP_MAX_LR overrides
|
| 153 |
+
float min_lr = 6e-5f; // CP_MIN_LR overrides (10% of max_lr)
|
| 154 |
+
bool use_muon = false; // CP_OPTIMIZER=muon
|
| 155 |
int warmup_steps = 91;
|
| 156 |
// CP_BF16=1 makes the Linears (wQ/wK/wV/wO, gate_up/down, lm_head matmul)
|
| 157 |
// bf16 with fp32 norms, fp32 residual stream and fp32 logits -- the scheme
|
|
|
|
| 984 |
cfg.max_steps = static_cast<int>(env_i64("CP_MAX_STEPS", cfg.max_steps));
|
| 985 |
cfg.warmup_steps = static_cast<int>(env_i64("CP_WARMUP", cfg.warmup_steps));
|
| 986 |
cfg.stable_steps = static_cast<int>(env_i64("CP_STABLE", cfg.stable_steps));
|
| 987 |
+
// LR BOUNDS FROM ENV (added 2026-09-18). max_lr/min_lr were hardcoded 6e-4 /
|
| 988 |
+
// 6e-5 and NOTHING read CP_MAX_LR or CP_MIN_LR -- every script in this
|
| 989 |
+
// project that set them was setting a variable the trainer ignored, and the
|
| 990 |
+
// floor could not be moved at all. Same failure family as CP_OPTIMIZER below.
|
| 991 |
+
if (const char* e = std::getenv("CP_MAX_LR")) cfg.max_lr = std::atof(e);
|
| 992 |
+
if (const char* e = std::getenv("CP_MIN_LR")) cfg.min_lr = std::atof(e);
|
| 993 |
+
// CP_OPTIMIZER=muon selects Muon for the >=2-D weight matrices with an aux
|
| 994 |
+
// AdamW path for everything else, mirroring bluscript_zero_ckpt.cpp's
|
| 995 |
+
// BLU_OPTIMIZER=muon. Until now this flag was READ NOWHERE: every CP run
|
| 996 |
+
// that passed CP_OPTIMIZER=muon in fact trained with AdamW.
|
| 997 |
+
cfg.use_muon = [] {
|
| 998 |
+
const char* v = std::getenv("CP_OPTIMIZER");
|
| 999 |
+
return v && (std::string(v) == "muon" || std::string(v) == "MUON");
|
| 1000 |
+
}();
|
| 1001 |
cfg.bf16 = env_i64("CP_BF16", cfg.bf16 ? 1 : 0) != 0;
|
| 1002 |
cfg.bf16_mask = static_cast<int>(env_i64("CP_BF16_MASK", cfg.bf16_mask));
|
| 1003 |
// Defaults ON when bf16 is requested at world_size>1, because DDP is broken
|
|
|
|
| 1732 |
// direction. Reduce in fp32 when that is suspected.
|
| 1733 |
zcfg.reduce_dtype = owt::zero::ReduceDtype::FP32;
|
| 1734 |
}
|
| 1735 |
+
// Muon config mirrors bluscript_zero_ckpt.cpp:1319-1347 exactly, with ONE
|
| 1736 |
+
// deliberate difference: lr and adamw_lr are both set to cfg.max_lr so the
|
| 1737 |
+
// ratio set_lr() preserves is 1:1 and BOTH paths run at the same learning
|
| 1738 |
+
// rate. Pretraining used 8e-4 / 6e-4 (a 4:3 Muon:AdamW ratio); here the
|
| 1739 |
+
// ablation calls for one shared value.
|
| 1740 |
+
owt::zero::MuonConfig mcfg;
|
| 1741 |
+
mcfg.collective = owt::zero::MuonCollective::REDUCE_SCATTER_ALL_GATHER;
|
| 1742 |
+
mcfg.target_buckets = static_cast<int>(env_i64("CP_MUON_BUCKETS", 6));
|
| 1743 |
+
mcfg.lr = cfg.max_lr;
|
| 1744 |
+
mcfg.momentum = 0.95f;
|
| 1745 |
+
mcfg.weight_decay = cfg.weight_decay;
|
| 1746 |
+
mcfg.ns_steps = 5;
|
| 1747 |
+
mcfg.nesterov = true;
|
| 1748 |
+
mcfg.adamw_lr = cfg.max_lr; // 1:1 with the Muon path
|
| 1749 |
+
mcfg.adamw_beta1 = zcfg.beta1;
|
| 1750 |
+
mcfg.adamw_beta2 = zcfg.beta2;
|
| 1751 |
+
mcfg.adamw_eps = zcfg.eps;
|
| 1752 |
+
mcfg.adamw_weight_decay = cfg.weight_decay;
|
| 1753 |
+
mcfg.exclude_1d_from_weight_decay = true;
|
| 1754 |
+
mcfg.max_grad_norm = zcfg.max_grad_norm;
|
| 1755 |
+
mcfg.reduce_dtype = zcfg.reduce_dtype;
|
| 1756 |
+
mcfg.init_broadcast = zcfg.init_broadcast;
|
| 1757 |
+
mcfg.verbose = is_master; // otherwise Muon runs SILENTLY and no
|
| 1758 |
+
// log line distinguishes it from AdamW
|
| 1759 |
for (auto& kv : params_by_dtype) {
|
| 1760 |
+
if (cfg.use_muon)
|
| 1761 |
+
zopts.push_back(std::make_unique<owt::zero::ShardedMuon>(kv.second, pg, mcfg));
|
| 1762 |
+
else if (cfg.zero_v2)
|
| 1763 |
zopts.push_back(std::make_unique<owt::zero::SymmetricShardedOptimizer>(kv.second, pg, zcfg));
|
| 1764 |
else
|
| 1765 |
zopts.push_back(std::make_unique<owt::zero::ShardedOptimizer>(kv.second, pg, zcfg));
|
|
|
|
| 1767 |
zgroup_label.push_back(OwnTensor::get_dtype_name(kv.first) + "/" + std::to_string(n));
|
| 1768 |
}
|
| 1769 |
if (is_master) {
|
| 1770 |
+
// Report what was actually BUILT. This line used to print cfg.zero_v2
|
| 1771 |
+
// unconditionally, so a Muon run was indistinguishable from an AdamW
|
| 1772 |
+
// one in the log -- the exact silent-failure shape this file keeps
|
| 1773 |
+
// hitting (CP_OPTIMIZER, CP_MAX_LR, CP_MIN_LR were all no-ops).
|
| 1774 |
+
std::cout << "[ZeRO-1] optimizer=" << (cfg.use_muon ? "MUON+adamw-aux" : "adamw")
|
| 1775 |
+
<< " variant=" << (cfg.use_muon ? "muon whole-tensor shard"
|
| 1776 |
+
: (cfg.zero_v2 ? "v2 reduce-scatter/all-gather"
|
| 1777 |
+
: "v1 reduce/broadcast"))
|
| 1778 |
<< " groups=" << zopts.size();
|
| 1779 |
for (auto& g : zgroup_label) std::cout << " [" << g << "]";
|
| 1780 |
std::cout << "\n[ZeRO-1] DataParallel is DISABLED (both would double-reduce)"
|