Compare commits

...
Author SHA1 Message Date
rock b790f5fb9b fix(llm-serving): run clef-candle from the fixed binary on the models PVC (#112)
Co-authored-by: rock <[email protected]>
2026-11-05 02:19:58 +00:00
rock 10ce4f8109 feat(llm-serving): serve clef-flash on candle-vllm (#109)
Co-authored-by: rock <[email protected]>
2026-11-05 01:40:42 +00:00
3 changed files with 100 additions and 1 deletions
+92
View File
@@ -0,0 +1,92 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: clef-candle
namespace: llm-serving
labels:
app.kubernetes.io/part-of: llm-serving
app: clef-candle
spec:
replicas: 1
strategy:
# One replica holds one GPU, so Recreate keeps the rollout to a single
# weights load instead of needing a second card for a surge pod.
type: Recreate
selector:
matchLabels:
app: clef-candle
template:
metadata:
labels:
app.kubernetes.io/part-of: llm-serving
# The clef-serve Service now selects this label (see clef-serve.yaml),
# so clients keep addressing clef-serve:80 unchanged. The reference
# pytorch Deployment must stay at replicas 0 while this runs, or the
# Service splits traffic across two different implementations.
app: clef-candle
spec:
# Required. Without the nvidia runtime class libcuda.so is never injected
# and candle-vllm panics in cudarc at startup.
runtimeClassName: nvidia
containers:
- name: candle
# :sm70 is built by .gitea/workflows/candle-vllm-sm70.yaml on every
# merge to main. It MUST be a build that contains the GDN conv fix
# (candle-vllm PR: feat/clef-systemone). Older :sm70 images zero the
# key channel band in causal_conv1d_fwd, which starves the delta rule
# and makes every linear-attention layer return zero. The symptom is
# a well-formed /v1/systemone response with wrong answers, not an error.
image: forgejo.riotpiao.com/riotpiao-poimen/candle-vllm:sm70
# :sm70 is a moving tag. Default IfNotPresent keeps a cached copy and a
# rebuilt image never reaches the pod, so a merged fix looks like it did
# not land. Always forces the pull on every pod start.
imagePullPolicy: Always
# Runs the fixed binary from the models PVC, not the one in the image.
# The published :sm70 predates the /v1/systemone route and the GDN conv
# fix (candle-vllm f3c00b2 is merged but CI has not republished the tag),
# so the in-image binary 404s on the route. The PVC copy at
# /mnt/models/bin/candle-vllm contains both fixes.
#
# RETIRE THIS once CI publishes a :sm70 built from f3c00b2: change the
# command back to /usr/local/bin/candle-vllm and delete the PVC copy.
command: ["/mnt/models/bin/candle-vllm"]
# clef-flash is a hybrid Qwen3_5 model: 8 full-attention layers plus 24
# GDN layers that carry per-sequence recurrent state. It runs on ONE
# card because the state is not shardable the way attention KV is.
args:
- --w
- /mnt/models/clef-flash
- --d
- "0"
- --dtype
- f16
- --p
- "8080"
- --max-num-seqs
- "4"
# About 66.8K KV tokens. Clef is a single-shot classifier-style
# endpoint, so it does not need the coder's pool.
- --kv-fraction
- "0.30"
# Prefix caching stays on: clef requests repeat the schema block.
- --prefill-chunk-size
- "1024"
ports:
- containerPort: 8080
resources:
limits:
cpu: "8"
memory: 32Gi
nvidia.com/gpu: "1"
requests:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: "1"
volumeMounts:
- name: models
mountPath: /mnt/models
readOnly: true
volumes:
- name: models
persistentVolumeClaim:
claimName: llm-models
+4 -1
View File
@@ -127,8 +127,11 @@ metadata:
labels: labels:
app.kubernetes.io/part-of: llm-serving app.kubernetes.io/part-of: llm-serving
spec: spec:
# Points at the candle-vllm implementation (clef-candle.yaml). Switching back
# to the reference pytorch server is this line plus that Deployment's replicas;
# no client changes, because the Service name and ClusterIP do not move.
selector: selector:
app: clef-serve app: clef-candle
ports: ports:
- name: http - name: http
port: 80 port: 80
+4
View File
@@ -21,6 +21,10 @@ resources:
# streams against 71.5 ms and 215 tok/s for the 4-bit MoE. The V100 has FP16 # streams against 71.5 ms and 215 tok/s for the 4-bit MoE. The V100 has FP16
# tensor cores and no INT4 ones, so 4-bit pays dequantisation on the SM while # tensor cores and no INT4 ones, so 4-bit pays dequantisation on the SM while
# the memory controller idles at 19%. # the memory controller idles at 19%.
# clef-candle.yaml serves clef-flash on candle-vllm (hybrid Qwen3_5, one GPU)
# and owns the clef-candle label that clef-serve.yaml's Service now selects.
# It must not sync against an image built before the GDN conv fix.
- clef-candle.yaml
- coder-14b-fp16.yaml - coder-14b-fp16.yaml
- clef-serve.yaml - clef-serve.yaml
# Stable client-facing name for the chat model. poimen-memory points at this Service, # Stable client-facing name for the chat model. poimen-memory points at this Service,