Skip to content

feat(server)!: add --gpu to choose the GPU on multi-GPU machines - #117

Merged
andy-yang-1 merged 3 commits into
mainfrom
feat/multi-gpu-select
Aug 24, 2026
Merged

feat(server)!: add --gpu to choose the GPU on multi-GPU machines#117
andy-yang-1 merged 3 commits into
mainfrom
feat/multi-gpu-select

Conversation

@jason-fxz

Copy link
Copy Markdown
Collaborator

Summary

ft serve always used cuda:0. This adds --gpu to pick the card:

ft serve --model ... --gpu GPU-2f3a9b1c   # UUID from nvidia-smi -L (a unique prefix is enough)
ft serve --model ... --gpu 1              # nvidia-smi index

ft bench bw and ft checkpoint take the same flag. The Desktop app uses it for its GPU picker.

Closes #99
Related #43 (fixed on the Desktop side),

What changed

  • --gpu is turned into CUDA_VISIBLE_DEVICES before the workers start. The engine itself is unchanged.
  • An index means the nvidia-smi number, not CUDA's own order. If CUDA_VISIBLE_DEVICES is already set, --gpu can only pick from that list.
  • A wrong GPU is reported before the model loads.
  • /v1/stats shows the GPU in use under gpus.
  • ft bench bw writes one profile per card (benchbw/<gpu-uuid>.json); the old benchbw.json still works.

Breaking change

ft checkpoint --device is removed. Use --gpu.

Tested on

8x RTX PRO 6000 Blackwell (96 GB), Xeon Platinum 8559C, Amazon Linux 2023, driver 595.71.05, CUDA 13.0, torch 2.11.0+cu130.
Checkpoint: Qwen3.8-27B BF16 as FTW

  • ft serve --gpu <uuid>, --gpu 6, and CUDA_VISIBLE_DEVICES=2,3 ... --gpu 1: the process lands on the expected card in nvidia-smi, /v1/stats.gpus matches, chat completions work.
  • Bad input (GPU-deadbeef, 99, 1,2, "", mixed UUID+index) is rejected with a clear error before loading.
  • ft bench bw --device 6 and ft daemon start ... -- --gpu <uuid prefix>: the per-card profile is written and /bench/profile returns the right card.
  • pytest tests/server tests/daemon tests/moe/test_hybrid_fetch.py: 570 passed.

Not Tested on Windows or on a box with different GPU models.

--gpu takes a GPU UUID (as nvidia-smi -L prints) or an nvidia-smi index.

It is applied as CUDA_VISIBLE_DEVICES in the parent before the workers spawn, so the engine still binds cuda:<rank>.

/v1/stats reports the engine's GPU under "gpus".

ft bench bw takes the same --gpu and writes one profile per GPU (benchbw/<gpu-uuid>.json); the legacy benchbw.json is still read by GPU name.

The daemon's /bench/profile returns the running serve's GPU profile.

BREAKING CHANGE: ft checkpoint --device is removed; use --gpu.
Copilot AI lite review requested due to automatic review settings August 24, 2026 00:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

…DEVICES

BREAKING CHANGE: ft bench bw --device is removed; use --gpu.
Splits the published id into _assigned_physical (UUID) and
_assigned_visible (CUDA ordinal). One process runs on one GPU, so
e4m3_native() judges that card instead of scanning every visible device.
@andy-yang-1

Copy link
Copy Markdown
Collaborator

@jason-fxz LGTM. I think we can merge it now

@andy-yang-1
andy-yang-1 merged commit 2757bb5 into main Aug 24, 2026
Samfisheryu pushed a commit to Samfisheryu/FreeToken that referenced this pull request Aug 26, 2026
…shML-org#117)

* feat(server)!: add --gpu to choose the GPU on multi-GPU machines

--gpu takes a GPU UUID (as nvidia-smi -L prints) or an nvidia-smi index.

It is applied as CUDA_VISIBLE_DEVICES in the parent before the workers spawn, so the engine still binds cuda:<rank>.

/v1/stats reports the engine's GPU under "gpus".

ft bench bw takes the same --gpu and writes one profile per GPU (benchbw/<gpu-uuid>.json); the legacy benchbw.json is still read by GPU name.

The daemon's /bench/profile returns the running serve's GPU profile.

BREAKING CHANGE: ft checkpoint --device is removed; use --gpu.

* refactor!: resolve --gpu via NVML and bind by UUID, not CUDA_VISIBLE_DEVICES

BREAKING CHANGE: ft bench bw --device is removed; use --gpu.

* refactor: name the id namespaces and drop the multi-device e4m3 scan

Splits the published id into _assigned_physical (UUID) and
_assigned_visible (CUDA ordinal). One process runs on one GPU, so
e4m3_native() judges that card instead of scanning every visible device.

(cherry picked from commit 2757bb5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

3 participants