param( [string]$DockerHost = "ssh://docker-gpu.cin.su", [string]$SshTarget = "docker-gpu.cin.su", [string]$VllmEnvFile = "core/deploy/docker-gpu/vllm/.env.example", [string]$LlamaEnvFile = "core/deploy/docker-gpu/llama-cpp/.env.example", [switch]$PlanOnly, [switch]$ConfigOnly, [switch]$Pull, [switch]$SkipPreflight, [switch]$SkipVllm, [switch]$SkipLlama, [switch]$SkipEvals, [int]$EndpointTimeoutSeconds = 900 ) $ErrorActionPreference = "Stop" function Invoke-Step { param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [string[]]$Command ) Write-Host "" Write-Host "== $Name" Write-Host ($Command -join " ") if ($PlanOnly) { return } & $Command[0] @($Command | Select-Object -Skip 1) if ($LASTEXITCODE -ne 0) { throw "Step failed with exit code ${LASTEXITCODE}: ${Name}" } } $steps = @() if (-not $SkipPreflight) { $steps += @{ Name = "GPU host preflight" Command = @( "powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "scripts/check_gpu_host.ps1", "-SshTarget", $SshTarget ) } } if (-not $SkipVllm) { $vllmCommand = @( "powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "scripts/deploy_vllm.ps1", "-DockerHost", $DockerHost, "-EnvFile", $VllmEnvFile ) if ($ConfigOnly) { $vllmCommand += "-ConfigOnly" } if ($Pull) { $vllmCommand += "-Pull" } $steps += @{ Name = "Deploy vLLM"; Command = $vllmCommand } } if (-not $SkipLlama) { $llamaCommand = @( "powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "scripts/deploy_llama_cpp.ps1", "-DockerHost", $DockerHost, "-EnvFile", $LlamaEnvFile ) if ($ConfigOnly) { $llamaCommand += "-ConfigOnly" } if ($Pull) { $llamaCommand += "-Pull" } $steps += @{ Name = "Deploy llama.cpp"; Command = $llamaCommand } } if (-not $ConfigOnly) { if (-not $SkipVllm) { $steps += @{ Name = "Wait vLLM endpoint" Command = @( "python", "scripts/wait_inference_endpoint.py", "--base-url", "http://docker-gpu.cin.su:8000", "--expected-model", "qwen3-4b-instruct", "--timeout", [string]$EndpointTimeoutSeconds, "--report", "reports/inference-endpoint-wait.vllm.json" ) } } if (-not $SkipLlama) { $steps += @{ Name = "Wait llama.cpp endpoint" Command = @( "python", "scripts/wait_inference_endpoint.py", "--base-url", "http://docker-gpu.cin.su:8080", "--expected-model", "devstral-1c-q4", "--timeout", [string]$EndpointTimeoutSeconds, "--report", "reports/inference-endpoint-wait.llama.json" ) } } if (-not $SkipEvals) { $steps += @{ Name = "Run live model evals" Command = @("python", "scripts/run_live_model_evals.py") } } } foreach ($step in $steps) { Invoke-Step -Name $step.Name -Command $step.Command } if ($PlanOnly) { Write-Host "" Write-Host "Plan complete. Re-run without -PlanOnly to execute." } else { Write-Host "" Write-Host "GPU stack flow completed." }