chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
# Kubernetes Deployment for the FunASR OpenAI-Compatible API
|
||||
|
||||
This folder provides a CPU-first Kubernetes template for the `examples/openai_api` server. Use it when you want an internal OpenAI-compatible speech endpoint reachable by agents, web backends, workflow engines, or batch workers inside a cluster.
|
||||
|
||||
The manifest is intentionally conservative:
|
||||
|
||||
- `ClusterIP` service by default, not a public `LoadBalancer`.
|
||||
- `FUNASR_DEVICE=cpu` by default so the image matches the portable Dockerfile.
|
||||
- A persistent cache volume mounted at `/root/.cache` so model downloads survive pod restarts.
|
||||
- `/health` startup, readiness, and liveness probes.
|
||||
- A memory-backed `/dev/shm` volume for PyTorch and audio preprocessing.
|
||||
|
||||
## 1. Build and push the image
|
||||
|
||||
From `examples/openai_api`:
|
||||
|
||||
```bash
|
||||
docker build -t registry.example.com/speech/funasr-api:cpu-latest .
|
||||
docker push registry.example.com/speech/funasr-api:cpu-latest
|
||||
```
|
||||
|
||||
Edit `kustomization.yaml` if you use a different registry, repository, or tag.
|
||||
|
||||
## 2. Deploy
|
||||
|
||||
```bash
|
||||
kubectl create namespace speech --dry-run=client -o yaml | kubectl apply -f -
|
||||
kubectl -n speech apply -k .
|
||||
kubectl -n speech rollout status deploy/funasr-api --timeout=15m
|
||||
```
|
||||
|
||||
Model download and first load can take several minutes. The `startupProbe` allows up to 10 minutes before Kubernetes restarts the container.
|
||||
|
||||
## 3. Smoke test
|
||||
|
||||
Keep the service private and verify it through `port-forward` first:
|
||||
|
||||
```bash
|
||||
kubectl -n speech port-forward svc/funasr-api 8000:8000
|
||||
```
|
||||
|
||||
From another terminal in `examples/openai_api`:
|
||||
|
||||
```bash
|
||||
python smoke_test.py --base-url http://localhost:8000
|
||||
```
|
||||
|
||||
For in-cluster clients, use `http://funasr-api.speech.svc.cluster.local:8000` as the direct HTTP base URL and `http://funasr-api.speech.svc.cluster.local:8000/v1` as the OpenAI SDK base URL.
|
||||
|
||||
## 4. Tune for your cluster
|
||||
|
||||
| Setting | Default | When to change it |
|
||||
|---|---|---|
|
||||
| `FUNASR_MODEL` | `sensevoice` | Use another alias after checking `/v1/models`. |
|
||||
| `FUNASR_DEVICE` | `cpu` | Set to `cuda` only after building a CUDA-capable image and configuring GPU scheduling. |
|
||||
| PVC size | `20Gi` | Increase when caching multiple models or large model revisions. |
|
||||
| Memory request | `8Gi` | Tune after observing startup and real audio workloads. |
|
||||
| Startup probe | 10 minutes | Increase if your registry, model hub, or storage backend is slow. |
|
||||
|
||||
## GPU notes
|
||||
|
||||
The example Dockerfile is CPU-first. For GPU clusters you need to adapt the image to CUDA-capable PyTorch/FunASR dependencies, then add your cluster's GPU scheduling fields, for example:
|
||||
|
||||
```yaml
|
||||
resources:
|
||||
limits:
|
||||
nvidia.com/gpu: "1"
|
||||
nodeSelector:
|
||||
nvidia.com/gpu.present: "true"
|
||||
```
|
||||
|
||||
Exact GPU labels, runtime classes, and device plugin configuration vary by Kubernetes distribution. Keep the service private until authentication, TLS, upload-size limits, and rate limits are in place.
|
||||
|
||||
## Operational checks
|
||||
|
||||
- Use `/health` for readiness and `/v1/models` to confirm model aliases.
|
||||
- Log model alias, device, audio duration, response format, latency, and error text.
|
||||
- Start with one replica because the cache PVC is `ReadWriteOnce`; scale horizontally with a registry image, per-pod cache, or a shared read-only model cache after measuring memory and startup time.
|
||||
- Put authentication and network policy in front of the service before exposing it outside a trusted namespace.
|
||||
- For Dify, n8n, or web backends inside the same cluster, point them at the Kubernetes service name instead of `localhost`.
|
||||
@@ -0,0 +1,80 @@
|
||||
# FunASR OpenAI 兼容 API Kubernetes 部署
|
||||
|
||||
这个目录提供 `examples/openai_api` 服务的 CPU-first Kubernetes 模板。适合在集群内部为 Agent、Web 后端、工作流引擎或批处理 worker 提供 OpenAI 兼容语音转写接口。
|
||||
|
||||
模板默认比较保守:
|
||||
|
||||
- 默认使用 `ClusterIP`,不直接暴露公网 `LoadBalancer`。
|
||||
- 默认 `FUNASR_DEVICE=cpu`,与便携 Dockerfile 匹配。
|
||||
- 在 `/root/.cache` 挂载持久化缓存卷,避免 Pod 重启后重复下载模型。
|
||||
- 使用 `/health` 做 startup、readiness 和 liveness probe。
|
||||
- 挂载内存型 `/dev/shm`,便于 PyTorch 和音频预处理使用。
|
||||
|
||||
## 1. 构建并推送镜像
|
||||
|
||||
在 `examples/openai_api` 目录中执行:
|
||||
|
||||
```bash
|
||||
docker build -t registry.example.com/speech/funasr-api:cpu-latest .
|
||||
docker push registry.example.com/speech/funasr-api:cpu-latest
|
||||
```
|
||||
|
||||
如果使用不同的 registry、repo 或 tag,请修改 `kustomization.yaml`。
|
||||
|
||||
## 2. 部署
|
||||
|
||||
```bash
|
||||
kubectl create namespace speech --dry-run=client -o yaml | kubectl apply -f -
|
||||
kubectl -n speech apply -k .
|
||||
kubectl -n speech rollout status deploy/funasr-api --timeout=15m
|
||||
```
|
||||
|
||||
模型下载和首次加载可能需要几分钟。`startupProbe` 默认允许最多 10 分钟,超过后 Kubernetes 才会重启容器。
|
||||
|
||||
## 3. Smoke test
|
||||
|
||||
建议先保持服务内网私有,通过 `port-forward` 验证:
|
||||
|
||||
```bash
|
||||
kubectl -n speech port-forward svc/funasr-api 8000:8000
|
||||
```
|
||||
|
||||
在另一个终端进入 `examples/openai_api` 后运行:
|
||||
|
||||
```bash
|
||||
python smoke_test.py --base-url http://localhost:8000
|
||||
```
|
||||
|
||||
集群内客户端可以使用 `http://funasr-api.speech.svc.cluster.local:8000` 作为直接 HTTP base URL,使用 `http://funasr-api.speech.svc.cluster.local:8000/v1` 作为 OpenAI SDK base URL。
|
||||
|
||||
## 4. 根据集群调整配置
|
||||
|
||||
| 配置 | 默认值 | 什么时候调整 |
|
||||
|---|---|---|
|
||||
| `FUNASR_MODEL` | `sensevoice` | 调用 `/v1/models` 后按需要切换模型别名。 |
|
||||
| `FUNASR_DEVICE` | `cpu` | 只有在镜像已适配 CUDA 且集群 GPU 调度已配置后才改成 `cuda`。 |
|
||||
| PVC 大小 | `20Gi` | 缓存多个模型或较大模型版本时增大。 |
|
||||
| 内存 request | `8Gi` | 根据启动过程和真实音频负载观测结果调整。 |
|
||||
| Startup probe | 10 分钟 | registry、模型下载或存储后端较慢时增大。 |
|
||||
|
||||
## GPU 说明
|
||||
|
||||
示例 Dockerfile 默认面向 CPU。GPU 集群需要先把镜像改成 CUDA-capable PyTorch/FunASR 依赖,再根据集群增加 GPU 调度字段,例如:
|
||||
|
||||
```yaml
|
||||
resources:
|
||||
limits:
|
||||
nvidia.com/gpu: "1"
|
||||
nodeSelector:
|
||||
nvidia.com/gpu.present: "true"
|
||||
```
|
||||
|
||||
不同 Kubernetes 发行版的 GPU label、runtime class 和 device plugin 配置并不相同。服务对外开放前,请先补齐鉴权、TLS、上传大小限制和限流。
|
||||
|
||||
## 运维检查
|
||||
|
||||
- 使用 `/health` 做就绪检查,使用 `/v1/models` 确认模型别名。
|
||||
- 记录模型别名、设备、音频时长、响应格式、延迟和错误文本。
|
||||
- 由于缓存 PVC 是 `ReadWriteOnce`,建议先从 1 个副本开始;横向扩容前先评估镜像、每 Pod 缓存或共享只读模型缓存方案。
|
||||
- 服务暴露到可信 namespace 之外前,先加鉴权和网络策略。
|
||||
- Dify、n8n 或 Web 后端在同一集群内访问时,应使用 Kubernetes service name,不要使用 `localhost`。
|
||||
@@ -0,0 +1,114 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: funasr-cache
|
||||
labels:
|
||||
app.kubernetes.io/name: funasr-api
|
||||
app.kubernetes.io/component: cache
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: funasr-api-config
|
||||
labels:
|
||||
app.kubernetes.io/name: funasr-api
|
||||
app.kubernetes.io/component: api
|
||||
data:
|
||||
FUNASR_PORT: "8000"
|
||||
FUNASR_DEVICE: "cpu"
|
||||
FUNASR_MODEL: "sensevoice"
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: funasr-api
|
||||
labels:
|
||||
app.kubernetes.io/name: funasr-api
|
||||
app.kubernetes.io/component: api
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: funasr-api
|
||||
app.kubernetes.io/component: api
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: funasr-api
|
||||
app.kubernetes.io/component: api
|
||||
spec:
|
||||
containers:
|
||||
- name: funasr-api
|
||||
image: funasr-api:local
|
||||
imagePullPolicy: IfNotPresent
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: funasr-api-config
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8000
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 60
|
||||
resources:
|
||||
requests:
|
||||
cpu: "2"
|
||||
memory: 8Gi
|
||||
limits:
|
||||
memory: 16Gi
|
||||
volumeMounts:
|
||||
- name: cache
|
||||
mountPath: /root/.cache
|
||||
- name: dshm
|
||||
mountPath: /dev/shm
|
||||
volumes:
|
||||
- name: cache
|
||||
persistentVolumeClaim:
|
||||
claimName: funasr-cache
|
||||
- name: dshm
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
sizeLimit: 2Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: funasr-api
|
||||
labels:
|
||||
app.kubernetes.io/name: funasr-api
|
||||
app.kubernetes.io/component: api
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: funasr-api
|
||||
app.kubernetes.io/component: api
|
||||
ports:
|
||||
- name: http
|
||||
port: 8000
|
||||
targetPort: http
|
||||
@@ -0,0 +1,8 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- funasr-api.yaml
|
||||
images:
|
||||
- name: funasr-api
|
||||
newName: registry.example.com/speech/funasr-api
|
||||
newTag: cpu-latest
|
||||
Reference in New Issue
Block a user