1
param(2
[string]$ERoot = "",3
[string]$ExperimentName = "Phase2_ParamSeq_WhisperBase_V4_0001",4
[string]$ModelName = "openai/whisper-base",5
[string]$DataProjectRoot = "",6
[string]$Manifest = "",7
[string]$AudioRoot = "",8
[string]$Vocab = "",9
[string]$ProgramRoot = "",10
[string]$OutputDir = "",11
[string]$LogsDir = "",12
[string]$RunDir = "",13
[string]$ExportDir = "",14
[switch]$ResumeFromPauseCkpt,15
[string]$ResumeFromCheckpoint = "",16
[switch]$AllowNonERoot,17
[switch]$DisableAutoResume,18
[switch]$DisableMemWarn,19
[double]$MemWarnRamThreshold = 0.90,20
[double]$MemWarnVramThreshold = 0.90,21
[int]$MemWarnCheckSteps = 25,22
[int]$MemWarnRepeatSteps = 200,23
[int]$PerDeviceTrainBatchSize = 1,24
[int]$PerDeviceEvalBatchSize = 1,25
[int]$GradientAccumulationSteps = 32,26
[bool]$GradientCheckpointing = $true,27
[double]$LearningRate = 3e-5,28
[double]$NumTrainEpochs = 3.0,29
[int]$MaxSteps = -1,30
[int]$SaveSteps = 250,31
[int]$EvalSteps = 250,32
[int]$SaveTotalLimit = 5,33
[double]$EvalRatio = 0.02,34
[double]$GpuMemFrac = 0.90,35
[double]$MaxSeconds = 6.0,36
[int]$MaxTargetLength = 768,37
[int]$NumWorkers = 0,38
[int]$PreextractReportEvery = 1000,39
[switch]$NoFeatureCache,40
[switch]$NoPreextractFeatures,41
[switch]$ValidateOnly,42
[switch]$DryRun43
)45
$ErrorActionPreference = "Stop"47
function Ensure-Dir {48
param([Parameter(Mandatory = $true)][string]$PathValue)49
try {50
New-Item -ItemType Directory -Force -Path $PathValue -ErrorAction Stop | Out-Null51
if (-not (Test-Path $PathValue)) {52
throw "Path still missing after create attempt."53
}54
} catch {55
throw "Failed to ensure directory '$PathValue': $($_.Exception.Message)"56
}57
}59
function Resolve-ExistingPath {60
param([Parameter(Mandatory = $true)][string]$PathValue)61
if (-not (Test-Path $PathValue)) {62
throw "Required path not found: $PathValue"63
}64
return (Resolve-Path $PathValue).Path65
}67
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path68
$projectDir = (Resolve-Path (Join-Path $scriptDir "..")).Path69
$mainDir = (Resolve-Path (Join-Path $projectDir "Main")).Path70
$workspaceDir = Split-Path -Parent $projectDir72
if (-not $DataProjectRoot) {73
$localManifest = Join-Path $projectDir "Audio\Samples\Wet_Main\manifest_full.jsonl"74
$v2ProjectRoot = Join-Path $workspaceDir "AI_Guitar_Pedal_V2"75
$v2Manifest = Join-Path $v2ProjectRoot "Audio\Samples\Wet_Main\manifest_full.jsonl"76
if (Test-Path $localManifest) {77
$DataProjectRoot = $projectDir78
} elseif (Test-Path $v2Manifest) {79
$DataProjectRoot = $v2ProjectRoot80
} else {81
throw "No complete Phase 2 data tree found. Pass -DataProjectRoot explicitly."82
}83
}84
$DataProjectRoot = Resolve-ExistingPath -PathValue $DataProjectRoot86
if (-not $ERoot) { $ERoot = Join-Path $mainDir "storage" }87
if (-not $Manifest) {88
$fullManifest = Join-Path $DataProjectRoot "Audio\Samples\Wet_Main\manifest_full.jsonl"89
if (Test-Path $fullManifest) {90
$Manifest = $fullManifest91
} else {92
$Manifest = Join-Path $DataProjectRoot "Audio\Samples\Wet_Main\manifest.jsonl"93
}94
}95
if (-not $AudioRoot) { $AudioRoot = Join-Path $DataProjectRoot "Audio\Samples\Wet_Main" }96
if (-not $Vocab) { $Vocab = Join-Path $mainDir "resources\dsp_control_vocab.json" }97
if (-not $ProgramRoot) { $ProgramRoot = Join-Path $DataProjectRoot "Audio\Presets\programs" }99
if (-not (Test-Path $ERoot)) {100
Ensure-Dir -PathValue $ERoot101
}102
$ERoot = (Resolve-Path $ERoot).Path103
$Manifest = Resolve-ExistingPath -PathValue $Manifest104
$AudioRoot = Resolve-ExistingPath -PathValue $AudioRoot105
$Vocab = Resolve-ExistingPath -PathValue $Vocab106
$ProgramRoot = Resolve-ExistingPath -PathValue $ProgramRoot108
$dataDir = Join-Path $ERoot "data"109
$artifactsDir = Join-Path $ERoot "artifacts"110
$checkpointsDir = Join-Path $artifactsDir "checkpoints"111
$artifactsLogsDir = Join-Path $artifactsDir "logs"112
$runsDir = Join-Path $artifactsDir "runs"113
$exportsDir = Join-Path $artifactsDir "exports"114
$cacheDir = Join-Path $ERoot "cache"115
$hfCacheDir = Join-Path $cacheDir "hf"116
$transformersCacheDir = Join-Path $cacheDir "transformers"117
$hubCacheDir = Join-Path $cacheDir "hub"118
$datasetsCacheDir = Join-Path $cacheDir "datasets"119
$whisperFeatureCacheDir = Join-Path $cacheDir "whisper\features"120
$torchExtensionsDir = Join-Path $cacheDir "torch\extensions"121
$torchCompileCacheDir = Join-Path $cacheDir "torch\compile_cache"122
$wandbCacheDir = Join-Path $cacheDir "wandb"123
$pipCacheDir = Join-Path $cacheDir "pip"124
$tmpDir = Join-Path $ERoot "tmp"126
$mustCreate = @(127
$dataDir,128
$artifactsDir,129
$checkpointsDir,130
$artifactsLogsDir,131
$runsDir,132
$exportsDir,133
$cacheDir,134
$hfCacheDir,135
$transformersCacheDir,136
$hubCacheDir,137
$datasetsCacheDir,138
$whisperFeatureCacheDir,139
$torchExtensionsDir,140
$torchCompileCacheDir,141
$wandbCacheDir,142
$pipCacheDir,143
$tmpDir144
)145
foreach ($dirPath in $mustCreate) {146
Ensure-Dir -PathValue $dirPath147
}149
if (-not $OutputDir) { $OutputDir = Join-Path $checkpointsDir $ExperimentName }150
if (-not $LogsDir) { $LogsDir = $artifactsLogsDir }151
if (-not $RunDir) { $RunDir = Join-Path $runsDir $ExperimentName }152
if (-not $ExportDir) { $ExportDir = Join-Path $exportsDir $ExperimentName }154
foreach ($dirPath in @($OutputDir, $LogsDir, $RunDir, $ExportDir)) {155
Ensure-Dir -PathValue $dirPath156
}158
$OutputDir = (Resolve-Path $OutputDir).Path159
$LogsDir = (Resolve-Path $LogsDir).Path160
$RunDir = (Resolve-Path $RunDir).Path161
$ExportDir = (Resolve-Path $ExportDir).Path163
$env:HF_HOME = $hfCacheDir164
$env:TRANSFORMERS_CACHE = $transformersCacheDir165
$env:HUGGINGFACE_HUB_CACHE = $hubCacheDir166
$env:HF_DATASETS_CACHE = $datasetsCacheDir167
$env:TORCH_EXTENSIONS_DIR = $torchExtensionsDir168
$env:TORCHINDUCTOR_CACHE_DIR = $torchCompileCacheDir169
$env:PYTORCH_CUDA_ALLOC_CONF = "expandable_segments:True"170
$env:XDG_CACHE_HOME = $cacheDir171
$env:TEMP = $tmpDir172
$env:TMP = $tmpDir173
$env:WANDB_DIR = Join-Path $artifactsLogsDir "wandb"174
$env:WANDB_CACHE_DIR = $wandbCacheDir175
$env:TENSORBOARD_LOGDIR = $runsDir176
$env:PIP_CACHE_DIR = $pipCacheDir178
Ensure-Dir -PathValue $env:WANDB_DIR180
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"181
$logPrefix = if ($ValidateOnly) { "phase2_validate" } elseif ($DryRun) { "phase2_dry_run" } else { "phase2_full" }182
$logPath = Join-Path $LogsDir ($logPrefix + "_" + $timestamp + ".log")184
$allowNonERootValue = if ($AllowNonERoot) { "true" } else { "false" }185
$dryRunValue = if ($DryRun) { "true" } else { "false" }186
$validateOnlyValue = if ($ValidateOnly) { "true" } else { "false" }187
$autoResumeValue = if ($DisableAutoResume) { "false" } else { "true" }188
$memWarnEnabledValue = if ($DisableMemWarn) { "false" } else { "true" }189
$featureCacheValue = if ($NoFeatureCache) { "false" } else { "true" }190
$preextractValue = if ($NoPreextractFeatures) { "false" } else { "true" }191
$gradientCheckpointingValue = if ($GradientCheckpointing) { "true" } else { "false" }193
$pythonExe = @(194
(Join-Path $mainDir ".venv\Scripts\python.exe"),195
(Join-Path $DataProjectRoot "Main\.venv\Scripts\python.exe")196
) | Where-Object { Test-Path $_ } | Select-Object -First 1197
if (-not $pythonExe) { $pythonExe = "python" }199
$args = @(200
"-u",201
"train_program_seq2seq.py",202
"--e_root", $ERoot,203
"--experiment_name", $ExperimentName,204
"--model_name", $ModelName,205
"--allow_non_e_root", $allowNonERootValue,206
"--dry_run", $dryRunValue,207
"--validate_only", $validateOnlyValue,208
"--manifest", $Manifest,209
"--audio_root", $AudioRoot,210
"--vocab", $Vocab,211
"--program_root", $ProgramRoot,212
"--output_dir", $OutputDir,213
"--log_dir", $RunDir,214
"--export_dir", $ExportDir,215
"--feature_cache_root", $whisperFeatureCacheDir,216
"--use_feature_cache", $featureCacheValue,217
"--preextract_features", $preextractValue,218
"--preextract_report_every", "$PreextractReportEvery",219
"--max_seconds", "$MaxSeconds",220
"--max_target_length", "$MaxTargetLength",221
"--eval_ratio", "$EvalRatio",222
"--per_device_train_batch_size", "$PerDeviceTrainBatchSize",223
"--per_device_eval_batch_size", "$PerDeviceEvalBatchSize",224
"--gradient_accumulation_steps", "$GradientAccumulationSteps",225
"--learning_rate", "$LearningRate",226
"--num_train_epochs", "$NumTrainEpochs",227
"--max_steps", "$MaxSteps",228
"--gradient_checkpointing", $gradientCheckpointingValue,229
"--gpu_mem_frac", "$GpuMemFrac",230
"--num_workers", "$NumWorkers",231
"--checkpoint_strategy", "steps",232
"--save_steps", "$SaveSteps",233
"--eval_steps", "$EvalSteps",234
"--save_total_limit", "$SaveTotalLimit",235
"--auto_resume", $autoResumeValue,236
"--mem_warn_enabled", $memWarnEnabledValue,237
"--mem_warn_ram_threshold", "$MemWarnRamThreshold",238
"--mem_warn_vram_threshold", "$MemWarnVramThreshold",239
"--mem_warn_check_steps", "$MemWarnCheckSteps",240
"--mem_warn_repeat_steps", "$MemWarnRepeatSteps"241
)243
if ($ResumeFromCheckpoint) {244
$args += @("--resume_from_checkpoint", (Resolve-ExistingPath -PathValue $ResumeFromCheckpoint))245
} elseif ($ResumeFromPauseCkpt) {246
$pauseCkpt = Join-Path $OutputDir "pause_ckpt"247
if (Test-Path $pauseCkpt) {248
$args += @("--resume_from_checkpoint", (Resolve-Path $pauseCkpt).Path)249
} else {250
Write-Output "[Warn] pause_ckpt not found, resume skipped: $pauseCkpt"251
}252
}254
$preview = $pythonExe + " " + (($args | ForEach-Object {255
if ($_ -match "\s") { '"' + $_ + '"' } else { $_ }256
}) -join " ")258
Write-Output "[Phase2] Effective paths"259
Write-Output " MainDir=$mainDir"260
Write-Output " DataProjectRoot=$DataProjectRoot"261
Write-Output " Python=$pythonExe"262
Write-Output " ERoot=$ERoot"263
Write-Output " ExperimentName=$ExperimentName"264
Write-Output " ModelName=$ModelName"265
Write-Output " Manifest=$Manifest"266
Write-Output " AudioRoot=$AudioRoot"267
Write-Output " Vocab=$Vocab"268
Write-Output " ProgramRoot=$ProgramRoot"269
Write-Output " OutputDir=$OutputDir"270
Write-Output " LogsDir=$LogsDir"271
Write-Output " RunDir=$RunDir"272
Write-Output " ExportDir=$ExportDir"273
Write-Output " FeatureCacheRoot=$whisperFeatureCacheDir"274
Write-Output " ValidateOnly=$validateOnlyValue"275
Write-Output " DryRun=$dryRunValue"276
Write-Output " MaxSteps=$MaxSteps"277
Write-Output " NumTrainEpochs=$NumTrainEpochs"278
Write-Output " MaxSeconds=$MaxSeconds"279
Write-Output " MaxTargetLength=$MaxTargetLength"280
Write-Output " EvalRatio=$EvalRatio"281
Write-Output " PerDeviceTrainBatchSize=$PerDeviceTrainBatchSize"282
Write-Output " GradientAccumulationSteps=$GradientAccumulationSteps"283
Write-Output " GradientCheckpointing=$gradientCheckpointingValue"284
Write-Output " LearningRate=$LearningRate"285
Write-Output " GpuMemFrac=$GpuMemFrac"286
Write-Output " AutoResume=$autoResumeValue"287
Write-Output " UseFeatureCache=$featureCacheValue"288
Write-Output " PreextractFeatures=$preextractValue"289
Write-Output " TEMP=$env:TEMP"290
Write-Output " HF_HOME=$env:HF_HOME"291
Write-Output " TRANSFORMERS_CACHE=$env:TRANSFORMERS_CACHE"292
Write-Output " HUGGINGFACE_HUB_CACHE=$env:HUGGINGFACE_HUB_CACHE"293
Write-Output " TORCH_EXTENSIONS_DIR=$env:TORCH_EXTENSIONS_DIR"294
Write-Output " TORCHINDUCTOR_CACHE_DIR=$env:TORCHINDUCTOR_CACHE_DIR"295
Write-Output " PYTORCH_CUDA_ALLOC_CONF=$env:PYTORCH_CUDA_ALLOC_CONF"296
Write-Output " WANDB_DIR=$env:WANDB_DIR"297
Write-Output " TENSORBOARD_LOGDIR=$env:TENSORBOARD_LOGDIR"298
Write-Output "[Launch] $preview"299
Write-Output "[Log] $logPath"300
Write-Output "[Hint] Tail log with: Get-Content -LiteralPath `"$logPath`" -Tail 80 -Wait"302
Push-Location $mainDir303
try {304
$oldEap = $ErrorActionPreference305
$ErrorActionPreference = "Continue"306
try {307
& $pythonExe @args 2>&1 | Tee-Object -FilePath $logPath308
} finally {309
$ErrorActionPreference = $oldEap310
}311
$exitCode = $LASTEXITCODE312
} finally {313
Pop-Location314
}316
Write-Output "[ExitCode] $exitCode"317
Write-Output "[Done] log: $logPath"318
exit $exitCode