Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions .github/workflows/vllm-gpu-smoke.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: vLLM GPU Smoke

# Manual GPU hello-world against Qwen/Qwen3-0.6B on a T4-class runner.
# Intended for Ken's offered `gpu-t4-4-core` larger-runner shape (or equivalent).
# Does not use the OGX ec2-github-runner / personal-PAT pattern.

on:
workflow_dispatch:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is this just for testing? Presume we will want to also run this on a schedule/PRs/etc.

inputs:
runner:
description: GitHub Actions runner label for the GPU host
required: true
default: gpu-t4-4-core
type: string

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions: {}

env:
CARGO_TERM_COLOR: always
VLLM_IMAGE: "docker.io/vllm/vllm-openai:v0.22.1-cu129@sha256:e1668bce9790a4b86682f8fcc99678153a13e12dc70e05348d8e239ffa474b05"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@leseb @franciscojavierarceo hey guys, @skamenan7 and I were talking and wanted to loop y'all in on an idea

For the OGX distro, we have automation in place in the repo for building and pushing our own vLLM CPU images with baked-in models, including Dependabot configurations for automatically updating the vLLM base image via a PR. This prevents us from being reliant on HuggingFace credentials/uptime for our testing.

I could replicate those workflows here or in another repo somewhere in Praxis if we were interested in using the same strategy for the testing here, but with CUDA-based GPU images rather than CPU

Let me know your thoughts - if y'all agree I can open a new tracker issue and assign myself for this work - it shouldn't be a heavy lift

@nathan-weinberg nathan-weinberg Aug 3, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

A PoC for this idea can be found here: https://github.com/praxis-proxy/ai/tree/vllm-gpu

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That's a good idea, once this merges.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Opened an issue to track and assigned myself: #692

VLLM_MODEL: "Qwen/Qwen3-0.6B"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can't we use a more capable model?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Perhaps Qwen/Qwen3.5-9B?


jobs:
vllm-gpu-hello:
runs-on: ${{ inputs.runner }}
timeout-minutes: 45
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Verify GPU and container runtime
run: |
nvidia-smi
Comment thread
skamenan7 marked this conversation as resolved.
if command -v docker >/dev/null 2>&1; then
echo "CONTAINER_RUNTIME=docker" >> "$GITHUB_ENV"
echo "GPU_FLAG=--gpus all" >> "$GITHUB_ENV"
docker info >/dev/null
elif command -v podman >/dev/null 2>&1; then
echo "CONTAINER_RUNTIME=podman" >> "$GITHUB_ENV"
echo "GPU_FLAG=--device nvidia.com/gpu=all" >> "$GITHUB_ENV"
podman info >/dev/null
else
echo "Neither docker nor podman is available on this runner" >&2
exit 1
fi

- name: Setup Rust
uses: praxis-proxy/conventions/.github/actions/setup-rust@7e1e8d97c2dc820d24b31f9a65b119c4d0e5342c # v0.1.0

- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0

- name: Pull vLLM CUDA image
run: |
"$CONTAINER_RUNTIME" pull "$VLLM_IMAGE"

- name: Start vLLM on GPU
run: |
"$CONTAINER_RUNTIME" run -d --name vllm \
$GPU_FLAG \
-p 8000:8000 \
-e HUGGING_FACE_HUB_TOKEN="${{ secrets.HUGGING_FACE_HUB_TOKEN }}" \
"$VLLM_IMAGE" \
--model "$VLLM_MODEL" \
--max-model-len 4096 \
--served-model-name "$VLLM_MODEL" \
--enable-auto-tool-choice \
--tool-call-parser hermes \
--reasoning-parser deepseek_r1 \
--gpu-memory-utilization 0.7

- name: Start OGX

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why?

run: |
uv run --with 'ogx[starter]' ogx run starter --insecure > /tmp/ogx.log 2>&1 &

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Medium] ogx[starter] is not version-pinned. A breaking OGX release will fail this workflow with no corresponding diff to bisect.

Pin to the version you're currently testing against:

          uv run --with 'ogx[starter]==<version>' ogx run starter --insecure > /tmp/ogx.log 2>&1 &

The existing vllm-integration.yaml has the same gap, but a new workflow shouldn't carry it forward.

echo $! > /tmp/ogx.pid

- name: Build Praxis
run: cargo build -p praxis-ai-proxy

- name: Wait for vLLM readiness
run: |
echo "Waiting for vLLM health and model endpoints..."
timeout 1200 bash -c 'until curl -sf http://127.0.0.1:8000/health > /dev/null 2>&1 && \
curl -sf http://127.0.0.1:8000/v1/models > /dev/null 2>&1; do
sleep 5
done'
echo "vLLM is ready"
curl -sf http://127.0.0.1:8000/v1/models | head -c 500
echo

- name: Wait for OGX readiness
run: |
echo "Waiting for OGX server..."
timeout 120 bash -c 'until curl -sf http://127.0.0.1:8321/v1/files > /dev/null 2>&1; do
sleep 2
done'
echo "OGX is ready"

- name: Run GPU hello-world smoke
run: |
uv run tests/integration/sdk/openai/test_openai_responses_vllm.py \
-s -k test_stateless_request

- name: vLLM container logs
if: failure()
run: |
"$CONTAINER_RUNTIME" logs vllm || true

- name: OGX logs
if: failure()
run: cat /tmp/ogx.log 2>/dev/null || echo "No OGX log found"

- name: Stop vLLM
if: always()
run: |
"$CONTAINER_RUNTIME" rm -f vllm || true

- name: Stop OGX
if: always()
run: |
if [ -f /tmp/ogx.pid ]; then
kill "$(cat /tmp/ogx.pid)" 2>/dev/null || true
fi
Loading