chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:25:10 +08:00
commit c397331b1e
3684 changed files with 990993 additions and 0 deletions
+80
View File
@@ -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