Spaces:
Running on Zero
Running on Zero
File size: 6,095 Bytes
f5c32d1 81ca02d f5c32d1 6464112 f5c32d1 e2d9ab4 f5c32d1 6464112 f5c32d1 6464112 f5c32d1 e2d9ab4 f5c32d1 6464112 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | ---
title: Qwen2.5 Coder 32B AWQ OpenAI API
emoji: 🚀
colorFrom: green
colorTo: yellow
sdk: gradio
sdk_version: 6.22.0
python_version: '3.12'
app_file: app.py
pinned: false
---
# Qwen2.5-Coder-32B AWQ — OpenAI-compatible ZeroGPU API
This Space serves `Qwen/Qwen2.5-Coder-32B-Instruct-AWQ` through an
OpenAI-compatible Chat Completions endpoint on Hugging Face ZeroGPU.
The runtime is pinned to the versions that were validated during the Space
startup work:
- PyTorch 2.11.0 / CUDA 13.0 wheels
- torchvision 0.26.0
- Transformers 5.14.1
- GPTQModel 7.3.2
- Gradio 6.22.0
The AWQ model is intentionally loaded lazily from inside the `@spaces.GPU`
function. This is required by this deployment because AWQ/Marlin performs real
CUDA work while `from_pretrained()` is running. Do not move model loading back
to module startup without retesting the Space on ZeroGPU.
## API
- `GET /health`
- `GET /v1/models`
- `POST /v1/chat/completions`
- `GET /web-search?q=...`
Accepted model names are the real model ID plus the compatibility aliases
`qwen2.5-coder-32b` and `qwen-coder`. Aliases for unrelated Qwen3 or 14B
weights are deliberately not accepted.
Example client configuration:
```text
OPENAI_BASE_URL=https://erinaldorodrigues-qwen-coder-api.hf.space/v1
OPENAI_API_BASE=https://erinaldorodrigues-qwen-coder-api.hf.space/v1
OPENAI_MODEL=qwen2.5-coder-32b
WEB_SEARCH_PROVIDER=custom
WEB_SEARCH_API=https://erinaldorodrigues-qwen-coder-api.hf.space/web-search
WEB_METHOD=GET
WEB_QUERY_PARAM=q
```
For direct calls to a ZeroGPU `hf.space` URL, use a valid Hugging Face access
token as `OPENAI_API_KEY` (for example, set `HF_TOKEN=hf_...` locally and then
`OPENAI_API_KEY=$HF_TOKEN`). OpenAI-compatible clients send this value as
`Authorization: Bearer ...`; the Hugging Face proxy can then attribute ZeroGPU
usage to the caller instead of the much smaller anonymous pool. The current
`app.py` does not perform application-level Bearer-token validation itself.
Never commit or paste the token into this repository.
## Tool calling
The backend accepts OpenAI-style `tools`, `tool_choice`, and
`parallel_tool_calls`. Tool definitions are normalized for Qwen's native chat template and textual
`<tool_call>...</tool_call>` outputs (plus the observed `<function_call>` fallback) are translated back to OpenAI
`message.tool_calls` objects with stable IDs, JSON-string arguments and
`finish_reason="tool_calls"`. The system prompt does not duplicate tool schemas;
the official Qwen native `<tools>` catalog remains the single schema source of
truth.
OpenClaude compatibility preserves request-level OpenAI `tool_choice` semantics.
`tool_choice="required"` is never silently downgraded to `none`; `auto` keeps the
tool catalog visible unless the current user turn explicitly disables tools.
Repository/codebase inspection is treated as real work; when OpenClaude exposes
`Glob`, repository-overview requests deterministically narrow the first call to
`Glob` so the model cannot answer from memory without inspecting the worktree.
Flow-state instructions may recommend final synthesis after usable evidence, but
they do not rewrite an explicit `required` request. Required/forced tool calls are
generated greedily at temperature 0.0, and a required call that fails to parse is
returned as an explicit upstream error rather than a false plain-text success.
When `parallel_tool_calls=true`, the prompt permits multiple independent tool
calls. Otherwise generation stops after the first complete tool call.
The Space generates tool calls; the calling client remains responsible for
executing client-side tools and returning their results in subsequent `tool`
messages. `/web-search` is a separate server-side search endpoint.
## Generation and compatibility
The default context limit is 131,072 tokens and default maximum output is 2,048
tokens. Contexts above Qwen2.5's native 32,768-token window automatically enable
YaRN RoPE scaling with a proportional factor (4.0 at the 131,072-token default).
`MAX_CONTEXT_TOKENS` is deliberately capped at 131,072 because that is the maximum
long-context length documented for this Qwen2.5-Coder checkpoint; the backend
refuses larger values instead of falsely advertising a context it cannot process.
At context lengths above 32,768 tokens, the ZeroGPU decorator requests
`size="xlarge"` (96 GB VRAM) rather than the 48 GB default `large` allocation.
This consumes 2x ZeroGPU quota and may queue longer, but avoids advertising a
131K context while allocating hardware that is too tight for the 32B model plus
its long-context KV cache.
The default request temperature is `0.0` (greedy). A caller may request a higher
temperature up to `MAX_TEMPERATURE`, but required/forced tool-call generations
always use `0.0` to make protocol JSON deterministic. Responses report prompt
and completion token counts, and `finish_reason="length"` is returned when a
normal completion exhausts the configured output budget.
`stream=true` returns OpenAI-style SSE framing. Tool deltas contain the `index`,
`id`, function name, and JSON-string arguments expected by OpenClaude. When the
client sends `stream_options={"include_usage": true}`, the final usage-only SSE
chunk is emitted before `[DONE]`. The current implementation finishes model
generation before emitting the first content/tool delta, so it is protocol
streaming rather than token-by-token low-latency streaming.
## Health
`/health` reports the configured model, `model_loaded`, `context_length`,
`yarn_enabled`, and `yarn_factor`. Because model loading is lazy, a healthy freshly
started process can report `model_loaded=false` until the first GPU inference
initializes the AWQ model.
## Tests
Run:
```bash
python -m unittest discover -p 'test_*.py'
```
The suite covers generation helpers, OpenAI/OpenClaude tool flow, the full
OpenClaude tool-call/result round trip, tool-call parsing, and web-search
fallbacks. The patched tree currently contains 107 deterministic unit/contract
tests, including direct `/v1/chat/completions` and SSE contract tests with the
GPU/model loader stubbed out.
|