# Plugsky GPU Share worker

This worker turns a personal GPU or Apple Silicon Mac into a **verified,
outbound-only** inference node for `plugsky-gpu-27b` (Underdog Saluki 27B IQ2).
It never asks you to open a router port. The worker polls Plugsky, runs the job
locally, and posts the result back.

## Quick install (recommended)

1. Open <https://plugsky.com/dashboard#gpu> and click **Add node**.
2. Copy the one-line command for the machine you want to add.
3. Paste it into Terminal (macOS/Linux) or PowerShell (Windows) and wait for
   `Install complete`.

**macOS / Linux**

```bash
curl -fsSL https://plugsky.com/gpu-worker/install.sh | bash -s -- --token sk-node-...
```

**Windows 10/11 — PowerShell 5.1+**

```powershell
$env:PLUGSKY_NODE_TOKEN="sk-node-..."; irm -useb https://plugsky.com/gpu-worker/install.ps1 | iex
```

The Windows installer needs **no admin rights**. It downloads a private Node.js
LTS copy, llama.cpp with CUDA, and the 7.89 GB model into
`%USERPROFILE%\.plugsky`, then starts the worker hidden and restarts it when you
sign in. The dashboard shows the node as **Online** within about 30 seconds
while the model loads. No router ports or firewall changes are needed.

To stop the Windows worker later, run `%USERPROFILE%\.plugsky\stop-worker.cmd`.
To see its log, open `%USERPROFILE%\.plugsky\worker.out.log`.

## Supported machines and minimums

- macOS 13+ on Apple Silicon (M1 or newer)
- Linux with an NVIDIA GPU (CUDA build of llama.cpp)
- Windows 10/11 **64-bit** with an NVIDIA GPU (CUDA build of llama.cpp)

**Minimum:** 7 GB VRAM/unified memory and 7 GB system RAM.
**Recommended:** 8 GB+ VRAM/unified and 16 GB RAM. 32K context needs 16 GB+;
the installer automatically uses 20/35/99 GPU layers and 8192/16384/32768
context below 10/20 GB VRAM, so 7-10 GB cards run with partial CPU offload.
AMD/Intel-only GPUs are not supported in v1. The preflight reports eligibility
before registration.

> **24 GB PC reported as 4 GB?** That is 32-bit Node.js: a 32-bit process can
> only see about 4 GB. The Windows installer now always uses a private 64-bit
> Node.js, and the updated preflight reads the real value through Windows WMI.
> If you run the preflight with an old system Node, install 64-bit Node.js or
> use the one-line installer.

## Model and licence

- Model: `ConwayResearch/Underdog-Saluki-27B-1.0`
- File: `Underdog-Saluki-27B-1.0-IQ2-mix.gguf` (7.89 GB)
- Licence: Apache-2.0
- Runtime: stock `llama.cpp` / `llama-server`
- Context: 32K text only (the optional vision projector is not enabled yet)

## Optional preflight

The check is local; nothing is uploaded. It reports CPU, memory, GPU/VRAM, free
disk, llama.cpp and model-file status. Exit code `0` means the hardware is
eligible; `2` means it is not.

```bash
# macOS / Linux
curl -fsSL https://plugsky.com/gpu-worker/preflight.js | node -

# Windows PowerShell — .Content is required; piping the response object fails
(iwr -useb https://plugsky.com/gpu-worker/preflight.js).Content | node -
```

## Register the node

The **Add node** button in the dashboard creates the node and shows its token
once. A new node starts as `pending` for non-admin accounts. Plugsky approves
it after verifying the heartbeat and hardware. If the token is lost, rotate it
in the dashboard; the old token stops working immediately.

## Manual install (advanced)

If you prefer to manage the runtime yourself:

```bash
# 1. Install Node.js 18+ and a CUDA/Metal build of llama.cpp, then verify:
llama-server --version

# 2. Download the model once (7.89 GB):
curl -L --fail --progress-bar \
  -o plugsky-gpu-27b.gguf \
  https://huggingface.co/ConwayResearch/Underdog-Saluki-27B-1.0/resolve/main/Underdog-Saluki-27B-1.0-IQ2-mix.gguf

# 3. Start the worker:
node worker.js \
  --token sk-node-... \
  --model-file ./plugsky-gpu-27b.gguf \
  --api https://api.plugsky.com
```

Windows PowerShell model download:

```powershell
Invoke-WebRequest -UseBasicParsing `
  -Uri "https://huggingface.co/ConwayResearch/Underdog-Saluki-27B-1.0/resolve/main/Underdog-Saluki-27B-1.0-IQ2-mix.gguf" `
  -OutFile "$env:USERPROFILE\.plugsky\plugsky-gpu-27b.gguf"
```

Useful flags:

| Flag | Meaning |
| --- | --- |
| `--port 18080` | Local llama-server port, bound to 127.0.0.1 |
| `--context 32768` | Context window; lower it if memory is tight |
| `--ngl N` | Layers to offload to Metal/CUDA (installer auto: 20/35/99 by VRAM) |
| `--once` | Claim and run one job, then exit |
| `--no-spawn` | Use an existing local llama-server |
| `--log-file ./gpu-worker.log` | Local log file |

The worker starts `llama-server` with `--jinja -fa on -np 1`, waits for health,
runs a small real benchmark, sends a heartbeat, and then polls for jobs.

## What the platform does with a job

1. A paid subscriber calls `POST /v1/chat/completions` with
   `"model": "plugsky-gpu-27b"`.
2. Plugsky queues a non-streaming job only when an approved worker is online.
3. A worker claims the job atomically, runs it locally, and posts the OpenAI
   response plus token usage.
4. Plugsky records usage, pays the operator 60%, and keeps 40% gross platform
   margin. If no worker answers within the queue window, the request falls back
   to the verified `plugsky-pro` NVIDIA lane.

## Safety limits

- Only approved nodes with a heartbeat younger than 90 seconds can claim work.
- One running job per node; leases expire after 45 seconds.
- Jobs contain only the request body and expire from the queue if no worker
  accepts them.
- The local llama-server is bound to `127.0.0.1`, never the public interface.
- Do not route sensitive data to contributed consumer hardware. This is a
  non-sensitive-workload pool.

## Troubleshooting

- **`Content : #!/usr/bin/env node` or `Expected ident` on Windows** — the old
  preflight command piped a response object. Use `.Content` (shown above) or,
  better, the one-line installer.
- **`llama-server` not found** — rerun the installer, or install a CUDA build
  of llama.cpp and ensure `llama-server.exe` is in `PATH`.
- **Out of memory** — the installer auto-selects 20/35/99 GPU layers and
  8192/16384/32768 context by VRAM. If you run manually on a 7-10 GB card, use
  `--ngl 20 --context 8192`. 7 GB VRAM/unified is the floor; 8 GB+ is
  recommended, and 16 GB+ for 32K.
- **`401 invalid node token`** — rotate the token in the dashboard, then rerun
  the installer with the new token.
- **No jobs** — the node must be approved, have `plugsky-gpu-27b` in
  `served_models`, and send heartbeats every 30 seconds.
- **Check `/api/nodes/jobs`** in the dashboard for per-job errors and events.
