apr_cli/model_ops_commands.rs
1
2#[derive(Subcommand, Debug)]
3pub enum ModelOpsCommands {
4 /// Fine-tune model with LoRA/QLoRA (GH-244)
5 #[cfg(feature = "training")]
6 Finetune {
7 /// Input model file
8 #[arg(value_name = "FILE")]
9 file: Option<PathBuf>,
10 /// Fine-tuning method: auto, full, lora, qlora
11 #[arg(long, short = 'm', default_value = "auto")]
12 method: String,
13 /// LoRA rank (default: auto-selected)
14 #[arg(long, short = 'r')]
15 rank: Option<u32>,
16 /// Available VRAM in GB
17 #[arg(long, default_value = "16.0")]
18 vram: f64,
19 /// Plan mode (estimate only)
20 #[arg(long)]
21 plan: bool,
22 /// Training data file (JSONL format)
23 #[arg(long, short = 'd', value_name = "FILE")]
24 data: Option<PathBuf>,
25 /// Output path (adapter dir or merged model)
26 #[arg(short, long)]
27 output: Option<PathBuf>,
28 /// Adapter path for merge mode
29 #[arg(long)]
30 adapter: Option<PathBuf>,
31 /// Merge adapter into base model
32 #[arg(long)]
33 merge: bool,
34 /// Training epochs
35 #[arg(long, default_value = "3")]
36 epochs: u32,
37 /// Learning rate. Default is rank-aware: the classic 2e-4 diverges at
38 /// the high LoRA ranks auto-selected to fill VRAM (e.g. rank 256), so
39 /// when omitted the recommendation is auto-lowered (2e-4 at rank<=32
40 /// down to ~2.5e-5 at rank 256). Pass an explicit value to override.
41 #[arg(long)]
42 learning_rate: Option<f64>,
43 /// Model size for planning (e.g., "7B", "1.5B")
44 #[arg(long, value_name = "SIZE")]
45 model_size: Option<String>,
46 /// Fine-tuning task: classify (sequence classification)
47 #[arg(long)]
48 task: Option<String>,
49 /// Number of classes for classification task
50 #[arg(long, default_value = "5")]
51 num_classes: usize,
52 /// Output format for checkpoints: apr, safetensors, or both (comma-separated)
53 #[arg(long, value_name = "FORMAT", default_value = "apr,safetensors")]
54 checkpoint_format: String,
55 /// Oversample minority classes to match majority (for imbalanced datasets)
56 #[arg(long)]
57 oversample: bool,
58 /// Maximum sequence length for GPU buffer allocation (lower = less VRAM)
59 #[arg(long, value_name = "LEN")]
60 max_seq_len: Option<usize>,
61 /// Quantize frozen weights to NF4 (4-bit) for QLoRA training (~8x VRAM savings)
62 #[arg(long)]
63 quantize_nf4: bool,
64 /// GPU indices for data-parallel training (e.g., "0,1" for dual GPU)
65 #[arg(long, value_name = "INDICES")]
66 gpus: Option<String>,
67 /// GPU backend selection: auto, cuda, wgpu
68 #[arg(long, default_value = "auto")]
69 gpu_backend: String,
70 /// Distributed training role: coordinator or worker
71 #[arg(long, value_name = "ROLE")]
72 role: Option<String>,
73 /// Address to bind (coordinator) or connect to (worker)
74 #[arg(long, value_name = "ADDR")]
75 bind: Option<String>,
76 /// Coordinator address for worker nodes (e.g., "intel:9000")
77 #[arg(long, value_name = "ADDR")]
78 coordinator: Option<String>,
79 /// Expected number of workers (coordinator only)
80 #[arg(long, value_name = "N")]
81 expect_workers: Option<usize>,
82 /// Wait for VRAM availability before training (timeout in seconds, 0 = no wait)
83 #[arg(long, value_name = "SECS", default_value = "0")]
84 wait_gpu: u64,
85 /// Multi-adapter training: data:checkpoint pairs (GPU-SHARE Phase 2)
86 /// Format: --adapters data/corpus-a.jsonl:checkpoints/adapter-a
87 /// Can be specified multiple times for concurrent adapter training.
88 #[arg(long, value_name = "DATA:CHECKPOINT")]
89 adapters: Vec<String>,
90
91 /// Multi-adapter config file: TOML with [[adapter]] entries (GPU-SHARE §2.4)
92 #[arg(long, value_name = "FILE")]
93 adapters_config: Option<PathBuf>,
94
95 /// Enable experimental CUDA MPS for concurrent GPU sharing (GPU-SHARE §1.5).
96 /// WARNING: A GPU fault in any MPS client will crash ALL clients on that GPU.
97 #[arg(long)]
98 experimental_mps: bool,
99
100 /// MPS thread percentage (1-100). Controls SM allocation per process.
101 /// Only effective with --experimental-mps. Default: 50.
102 #[arg(long, value_name = "PCT", default_value = "50")]
103 gpu_share: u32,
104
105 /// PMAT-486: Enable StepProfiler for per-phase wall-clock timing
106 #[arg(long)]
107 profile: bool,
108 },
109 /// Prune model (structured/unstructured pruning) (GH-247)
110 Prune {
111 /// Input model file
112 #[arg(value_name = "FILE")]
113 file: PathBuf,
114 /// Pruning method: magnitude, structured, depth, width, wanda, sparsegpt
115 #[arg(long, short = 'm', default_value = "magnitude")]
116 method: String,
117 /// Target pruning ratio (0-1)
118 #[arg(long, default_value = "0.5")]
119 target_ratio: f32,
120 /// Sparsity level (0-1)
121 #[arg(long, default_value = "0.0")]
122 sparsity: f32,
123 /// Output file path
124 #[arg(short, long)]
125 output: Option<PathBuf>,
126 /// Layers to remove for depth pruning (e.g., "20-24")
127 #[arg(long)]
128 remove_layers: Option<String>,
129 /// Analyze mode (identify pruning opportunities)
130 #[arg(long)]
131 analyze: bool,
132 /// Plan mode (estimate only)
133 #[arg(long)]
134 plan: bool,
135 /// Calibration data file
136 #[arg(long, value_name = "FILE")]
137 calibration: Option<PathBuf>,
138 },
139 /// Knowledge distillation (teacher -> student) (GH-247, ALB-011)
140 Distill {
141 /// Teacher model file (positional, for file-based mode)
142 #[arg(value_name = "TEACHER")]
143 teacher: Option<PathBuf>,
144 /// Student model file
145 #[arg(long, value_name = "FILE")]
146 student: Option<PathBuf>,
147 /// Training data file
148 #[arg(long, short = 'd', value_name = "FILE")]
149 data: Option<PathBuf>,
150 /// Output file path
151 #[arg(short, long)]
152 output: Option<PathBuf>,
153 /// Distillation strategy: standard, progressive, ensemble
154 #[arg(long, default_value = "standard")]
155 strategy: String,
156 /// Temperature for softmax scaling
157 #[arg(long, default_value = "3.0")]
158 temperature: f64,
159 /// Alpha weight for KL vs task loss
160 #[arg(long, default_value = "0.7")]
161 alpha: f64,
162 /// Training epochs
163 #[arg(long, default_value = "3")]
164 epochs: u32,
165 /// Plan mode (estimate only)
166 #[arg(long)]
167 plan: bool,
168 /// YAML config file for two-stage distillation (ALB-011)
169 #[arg(long, value_name = "FILE")]
170 config: Option<PathBuf>,
171 /// Distillation stage: precompute, train (logit KD), or generate (text-based, GH-455)
172 #[arg(long, value_name = "STAGE")]
173 stage: Option<String>,
174 /// SPEC-DISTILL-001 Phase 3-prep (PMAT-697): teacher/student backend
175 /// selector. `fixture` (default) uses the in-memory FixtureTeacher
176 /// + FixtureStudent (CPU-only, useful for plumbing tests + CI).
177 /// `cuda` constructs CudaTrainerTeacher + CudaStudentProvider from
178 /// the on-disk teacher / student checkpoints — required for the
179 /// real F-DISTILL-SMOKE-001 falsifier on GPU hardware.
180 #[arg(long, value_name = "BACKEND", default_value = "fixture")]
181 backend: String,
182 /// SPEC-DISTILL-001 Phase 4 Stage B-2: real-corpus training data.
183 /// Path to a directory containing `.bin` token shards (u32 LE,
184 /// matching the format `apr tokenize encode-corpus` produces).
185 /// When set, the distillation pipeline reads batches from this
186 /// directory via `ShardBatchSource`. When unset (the default),
187 /// the pipeline uses `SyntheticBatchSource` (identity-mapping
188 /// smoke; see PMAT-698m / PMAT-698o).
189 ///
190 /// Phase 4 50K-step dispatch sets this to a tokenized Python
191 /// corpus directory.
192 #[arg(long, value_name = "DIR")]
193 dataset: Option<PathBuf>,
194 },
195}