GTE-large部署教程:Kubernetes Helm Chart封装与弹性扩缩容实践
GTE-large部署教程:Kubernetes Helm Chart封装与弹性扩缩容实践
1. 引言
如果你正在寻找一个功能强大的中文文本向量模型,并且希望它能轻松识别实体、分析情感、抽取关系,那么GTE-large很可能就是你的答案。这个基于ModelScope的模型,集成了命名实体识别、关系抽取、事件抽取、情感分析、文本分类和问答六大核心功能,就像一个全能的语言理解助手。
但问题来了:如何让这样一个功能丰富的模型应用,在企业环境中稳定、高效地运行?如果只是简单地在服务器上跑个Python脚本,你会面临部署复杂、难以扩展、运维困难等一系列挑战。
今天,我就带你走一条更专业的路线:将GTE-large应用封装成Kubernetes Helm Chart,并实现弹性扩缩容。无论你是刚开始接触Kubernetes,还是已经有一定经验的开发者,这篇文章都会给你一套可以直接落地的解决方案。
2. 项目概览与核心价值
2.1 GTE-large是什么?
GTE-large是一个专门针对中文文本设计的通用领域向量模型。它的全称是“GTE文本向量-中文-通用领域-large”,基于ModelScope平台上的iic/nlp_gte_sentence-embedding_chinese-large模型构建。
这个模型最吸引人的地方在于它的多功能性。想象一下,你有一个文本处理的需求,传统做法可能需要部署多个不同的模型:一个做实体识别,一个做情感分析,一个做关系抽取……每个模型都有自己的部署和维护成本。而GTE-large把这些功能都集成在了一起。
2.2 核心功能一览
让我们具体看看它能做什么:
- 命名实体识别:自动识别文本中的人名、地名、组织机构名、时间等实体。比如从“2022年北京冬奥会在北京举行”中,它能识别出“2022年”、“北京冬奥会”、“北京”等关键信息。
- 关系抽取:找出实体之间的关系。比如“姚明参加了2008年北京奥运会”,它能识别出“姚明”和“北京奥运会”之间的“参赛”关系。
- 事件抽取:识别事件及其相关要素。对于新闻报道类文本特别有用。
- 情感分析:分析文本中的情感倾向,识别属性词和情感词。
- 文本分类:将文本归类到预定义的类别中。
- 问答系统:基于给定的上下文回答问题。
2.3 为什么需要Kubernetes部署?
你可能会问:这个应用不是已经提供了启动脚本吗?直接运行不就行了?
确实,对于个人使用或小规模测试,直接运行bash /root/build/start.sh是最简单的方式。但如果你考虑的是:
- 高可用性:服务不能因为单点故障而中断
- 弹性伸缩:流量高峰时自动扩容,闲时自动缩容以节省资源
- 简化部署:一键部署整个应用及其依赖
- 统一管理:使用标准化的方式管理配置、日志、监控
- 资源隔离:确保应用不会影响同一服务器上的其他服务
那么,Kubernetes就是目前最成熟的解决方案。而Helm作为Kubernetes的包管理器,能让部署过程变得更加简单和可重复。
3. 环境准备与基础部署
3.1 基础环境要求
在开始之前,确保你有一个可用的Kubernetes集群。如果你还没有,可以考虑以下几种方式:
- 本地开发:使用Minikube或Kind搭建本地集群
- 云服务:使用阿里云ACK、腾讯云TKE、华为云CCE等托管服务
- 自建集群:使用kubeadm等工具自建
无论选择哪种方式,你都需要安装以下工具:
- kubectl:Kubernetes命令行工具
- Helm:Kubernetes包管理器(版本3.x)
3.2 传统部署方式回顾
让我们先快速回顾一下传统的部署方式,这样你就能更清楚地看到Kubernetes部署的优势。
传统的部署步骤大概是这样的:
# 1. 准备环境
cd /root/build/
# 2. 安装依赖(假设requirements.txt存在)
pip install -r requirements.txt
# 3. 启动服务
bash start.sh
对应的start.sh内容可能类似:
#!/bin/bash
python app.py
而app.py的核心部分是这样的:
from flask import Flask, request, jsonify
import torch
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
app = Flask(__name__)
# 加载模型
ner_pipeline = pipeline(Tasks.named_entity_recognition,
'iic/nlp_gte_sentence-embedding_chinese-large')
@app.route('/predict', methods=['POST'])
def predict():
data = request.json
task_type = data.get('task_type', 'ner')
input_text = data.get('input_text', '')
# 根据任务类型调用不同的处理逻辑
if task_type == 'ner':
result = ner_pipeline(input_text)
# ... 其他任务类型的处理
return jsonify({'result': result})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
这种方式简单直接,但存在几个明显问题:
- 单点故障:进程挂了服务就停了
- 难以扩展:手动启动多个实例很麻烦
- 配置管理困难:修改配置需要重启服务
- 资源隔离差:可能影响同一服务器上的其他应用
4. Docker镜像构建
4.1 创建Dockerfile
我们要做的第一步,就是把应用打包成Docker镜像。这样无论在哪里运行,环境都是一致的。
创建一个Dockerfile文件:
# 使用Python官方镜像作为基础
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
g++ \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 创建非root用户运行应用(安全最佳实践)
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
# 暴露端口
EXPOSE 5000
# 启动命令
CMD ["python", "app.py"]
4.2 创建requirements.txt
确保你的requirements.txt包含所有必要的依赖:
Flask==2.3.3
modelscope==1.9.5
torch==2.0.1
transformers==4.35.2
4.3 构建和测试镜像
构建Docker镜像:
# 构建镜像
docker build -t gte-large-app:1.0.0 .
# 测试运行
docker run -p 5000:5000 gte-large-app:1.0.0
测试API是否正常工作:
# 测试命名实体识别
curl -X POST http://localhost:5000/predict \
-H "Content-Type: application/json" \
-d '{
"task_type": "ner",
"input_text": "2022年北京冬奥会在北京举行"
}'
如果一切正常,你应该能看到类似这样的响应:
{
"result": {
"text": "2022年北京冬奥会在北京举行",
"entities": [
{"type": "TIME", "start": 0, "end": 5, "span": "2022年"},
{"type": "EVENT", "start": 5, "end": 11, "span": "北京冬奥会"},
{"type": "LOC", "start": 13, "end": 15, "span": "北京"}
]
}
}
5. Helm Chart设计与实现
5.1 Helm Chart基础结构
Helm Chart是Kubernetes应用的打包格式。让我们创建一个完整的Chart结构:
gte-large-chart/
├── Chart.yaml # Chart的元数据
├── values.yaml # 默认配置值
├── templates/ # Kubernetes资源模板
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── hpa.yaml
│ └── configmap.yaml
└── charts/ # 依赖的Charts(可选)
5.2 Chart.yaml - 定义Chart元数据
apiVersion: v2
name: gte-large
description: GTE文本向量-中文-通用领域-large多任务Web应用
type: application
version: 1.0.0
appVersion: "1.0.0"
# 依赖项(如果有的话)
dependencies:
- name: redis
version: "17.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
5.3 values.yaml - 配置参数
这是Helm Chart的核心配置文件,所有可配置的参数都在这里:
# 副本数配置
replicaCount: 2
# 镜像配置
image:
repository: your-registry/gte-large-app
tag: "1.0.0"
pullPolicy: IfNotPresent
# 服务配置
service:
type: ClusterIP
port: 5000
targetPort: 5000
# 资源限制
resources:
requests:
memory: "4Gi"
cpu: "1000m"
limits:
memory: "8Gi"
cpu: "2000m"
# 自动扩缩容配置
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
# 环境变量配置
env:
- name: FLASK_ENV
value: "production"
- name: MODEL_CACHE_DIR
value: "/app/model_cache"
# 持久化存储配置
persistence:
enabled: true
storageClass: "standard"
accessMode: ReadWriteOnce
size: 10Gi
# Ingress配置(如果需要外部访问)
ingress:
enabled: false
className: "nginx"
hosts:
- host: gte-large.example.com
paths:
- path: /
pathType: Prefix
6. Kubernetes资源模板
6.1 Deployment模板
创建templates/deployment.yaml,这是应用的核心部署配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "gte-large.fullname" . }}
labels:
{{- include "gte-large.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "gte-large.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "gte-large.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
name: http
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 60 # 模型加载需要时间
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 60
periodSeconds: 5
volumeMounts:
- name: model-cache
mountPath: /app/model_cache
volumes:
- name: model-cache
{{- if .Values.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ include "gte-large.fullname" . }}-pvc
{{- else }}
emptyDir: {}
{{- end }}
6.2 Service模板
创建templates/service.yaml,定义如何访问服务:
apiVersion: v1
kind: Service
metadata:
name: {{ include "gte-large.fullname" . }}
labels:
{{- include "gte-large.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetPort }}
protocol: TCP
name: http
selector:
{{- include "gte-large.selectorLabels" . | nindent 4 }}
6.3 Horizontal Pod Autoscaler模板
创建templates/hpa.yaml,实现自动扩缩容:
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "gte-large.fullname" . }}
labels:
{{- include "gte-large.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "gte-large.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
6.4 辅助模板文件
创建templates/_helpers.tpl,定义一些可重用的模板函数:
{{- define "gte-fullname" -}}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- define "gte-labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{- define "gte-selectorLabels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
7. 部署与测试
7.1 部署到Kubernetes集群
现在,让我们把整个应用部署到Kubernetes集群:
# 1. 添加Helm仓库(如果需要)
helm repo add bitnami https://charts.bitnami.com/bitnami
# 2. 更新依赖
helm dependency update gte-large-chart
# 3. 安装Chart
helm install gte-large ./gte-large-chart \
--namespace gte-namespace \
--create-namespace \
--set image.repository=your-registry/gte-large-app \
--set image.tag=1.0.0
7.2 验证部署状态
检查部署状态:
# 查看所有资源状态
kubectl get all -n gte-namespace
# 查看Pod状态
kubectl get pods -n gte-namespace -l app.kubernetes.io/name=gte-large
# 查看服务
kubectl get svc -n gte-namespace
# 查看HPA状态
kubectl get hpa -n gte-namespace
7.3 测试API接口
通过端口转发测试服务:
# 端口转发到本地
kubectl port-forward svc/gte-large 5000:5000 -n gte-namespace
# 在另一个终端测试API
curl -X POST http://localhost:5000/predict \
-H "Content-Type: application/json" \
-d '{
"task_type": "ner",
"input_text": "2022年北京冬奥会在北京举行"
}'
7.4 测试不同任务类型
让我们测试一下其他功能:
import requests
import json
base_url = "http://localhost:5000"
# 测试情感分析
def test_sentiment():
payload = {
"task_type": "sentiment",
"input_text": "这个产品的质量非常好,我非常满意"
}
response = requests.post(f"{base_url}/predict", json=payload)
print("情感分析结果:", json.dumps(response.json(), indent=2, ensure_ascii=False))
# 测试文本分类
def test_classification():
payload = {
"task_type": "classification",
"input_text": "今天天气真好,适合出去散步"
}
response = requests.post(f"{base_url}/predict", json=payload)
print("文本分类结果:", json.dumps(response.json(), indent=2, ensure_ascii=False))
# 测试问答系统
def test_qa():
payload = {
"task_type": "qa",
"input_text": "北京是中国的首都|北京是哪个国家的首都?"
}
response = requests.post(f"{base_url}/predict", json=payload)
print("问答结果:", json.dumps(response.json(), indent=2, ensure_ascii=False))
if __name__ == "__main__":
test_sentiment()
test_classification()
test_qa()
8. 弹性扩缩容实战
8.1 理解HPA工作原理
Horizontal Pod Autoscaler(HPA)是Kubernetes的自动扩缩容组件。它根据你定义的指标(如CPU、内存使用率)自动调整Pod的数量。
在我们的配置中,HPA会监控:
- CPU使用率:目标70%
- 内存使用率:目标80%
当使用率超过目标值时,HPA会自动增加Pod数量;当使用率低于目标值时,会自动减少Pod数量。
8.2 模拟流量压力测试
让我们创建一个简单的压力测试脚本,观察HPA如何工作:
import concurrent.futures
import requests
import time
import json
def send_request(task_type, text):
"""发送单个请求"""
payload = {
"task_type": task_type,
"input_text": text
}
try:
response = requests.post(
"http://localhost:5000/predict",
json=payload,
timeout=10
)
return response.status_code
except Exception as e:
return str(e)
def stress_test(concurrent_requests=50, duration=60):
"""压力测试"""
tasks = ["ner", "sentiment", "classification"]
texts = [
"2022年北京冬奥会在北京举行",
"这个产品的质量非常好,我非常满意",
"今天天气真好,适合出去散步",
"人工智能技术正在快速发展",
"中国的经济发展取得了显著成就"
]
print(f"开始压力测试:{concurrent_requests}并发,持续{duration}秒")
start_time = time.time()
request_count = 0
with concurrent.futures.ThreadPoolExecutor(max_workers=concurrent_requests) as executor:
futures = []
while time.time() - start_time < duration:
for _ in range(concurrent_requests):
task_type = tasks[request_count % len(tasks)]
text = texts[request_count % len(texts)]
futures.append(executor.submit(send_request, task_type, text))
request_count += 1
time.sleep(0.1)
# 收集结果
results = [future.result() for future in futures]
success_count = sum(1 for r in results if r == 200)
print(f"测试完成:总请求数={request_count}, 成功数={success_count}")
return request_count, success_count
if __name__ == "__main__":
# 先观察当前Pod数量
print("压力测试前,观察当前状态...")
# 运行压力测试
total_requests, success_requests = stress_test(concurrent_requests=30, duration=120)
print(f"\n测试总结:")
print(f"总请求数: {total_requests}")
print(f"成功请求数: {success_requests}")
print(f"成功率: {success_requests/total_requests*100:.2f}%")
8.3 监控扩缩容过程
在压力测试期间,打开另一个终端观察HPA和Pod的变化:
# 实时监控Pod变化
watch -n 2 'kubectl get pods -n gte-namespace'
# 实时监控HPA状态
watch -n 2 'kubectl get hpa -n gte-namespace'
# 查看Pod资源使用情况
kubectl top pods -n gte-namespace
你会看到:
- 压力测试开始时,Pod的CPU和内存使用率上升
- 当使用率超过阈值(CPU 70%,内存 80%)时,HPA开始创建新的Pod
- 新的Pod启动并加入服务
- 压力测试结束后,使用率下降,HPA逐渐减少Pod数量
8.4 自定义指标扩缩容
除了CPU和内存,你还可以基于自定义指标进行扩缩容。比如基于请求数:
# 在values.yaml中添加自定义指标
autoscaling:
customMetrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100" # 每个Pod每秒处理100个请求
然后需要安装Prometheus和相应的适配器来提供这些指标。
9. 生产环境优化建议
9.1 性能优化配置
对于生产环境,你可能需要调整一些配置:
# 优化后的values.yaml配置
resources:
requests:
memory: "8Gi" # 增加内存请求
cpu: "2000m" # 增加CPU请求
limits:
memory: "16Gi" # 增加内存限制
cpu: "4000m" # 增加CPU限制
# 调整探针配置
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 120 # 给模型加载更多时间
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 120
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
# 添加启动探针
startupProbe:
httpGet:
path: /health
port: http
failureThreshold: 30 # 最多尝试30次
periodSeconds: 10
9.2 高可用性配置
# 使用Pod反亲和性,确保Pod分布在不同的节点上
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- gte-large
topologyKey: kubernetes.io/hostname
# 配置多个副本,分布在不同的可用区
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/name: gte-large
9.3 监控与日志
添加监控和日志配置:
# 添加Prometheus监控注解
prometheus:
enabled: true
scrape: true
path: /metrics
port: 5000
# 配置结构化日志
env:
- name: LOG_LEVEL
value: "INFO"
- name: LOG_FORMAT
value: "json"
- name: FLASK_ENV
value: "production"
9.4 安全加固
# 安全上下文配置
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# 网络策略
networkPolicy:
enabled: true
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: gte-ingress
ports:
- port: 5000
protocol: TCP
10. 故障排查与维护
10.1 常见问题及解决方案
问题1:Pod启动失败,模型加载超时
现象:Pod一直处于CrashLoopBackOff状态,日志显示模型加载超时。
解决方案:
# 调整启动探针和资源限制
startupProbe:
httpGet:
path: /health
port: http
failureThreshold: 60 # 增加重试次数
periodSeconds: 10
resources:
requests:
memory: "12Gi" # 增加内存
cpu: "3000m"
问题2:内存不足导致OOM Kill
现象:Pod被终止,事件显示OOMKilled。
解决方案:
# 查看内存使用情况
kubectl top pods -n gte-namespace
# 调整内存限制
kubectl edit deployment gte-large -n gte-namespace
# 修改resources.limits.memory为更大的值
问题3:服务响应缓慢
现象:API响应时间变长,客户端超时。
解决方案:
- 检查HPA是否正常工作
- 增加副本数
- 优化模型加载策略(使用模型缓存)
10.2 日常维护命令
# 查看应用状态
kubectl get all -n gte-namespace -l app.kubernetes.io/name=gte-large
# 查看Pod日志
kubectl logs -f deployment/gte-large -n gte-namespace
# 进入Pod调试
kubectl exec -it deployment/gte-large -n gte-namespace -- /bin/bash
# 查看HPA事件
kubectl describe hpa gte-large -n gte-namespace
# 滚动更新(修改镜像版本后)
helm upgrade gte-large ./gte-large-chart \
--namespace gte-namespace \
--set image.tag=1.0.1
# 回滚到上一个版本
helm rollback gte-large 1 -n gte-namespace
# 清理资源
helm uninstall gte-large -n gte-namespace
kubectl delete namespace gte-namespace
10.3 监控告警配置
建议配置以下监控告警:
- Pod重启频繁告警:5分钟内重启超过3次
- CPU使用率告警:持续5分钟超过85%
- 内存使用率告警:持续5分钟超过90%
- 服务可用性告警:HTTP状态码5xx比例超过5%
- 响应时间告警:P95响应时间超过2秒
11. 总结
通过本文的实践,我们成功地将GTE-large多任务Web应用从简单的单机部署,升级为基于Kubernetes和Helm的现代化云原生部署方案。让我们回顾一下关键收获:
11.1 核心价值实现
-
标准化部署:通过Helm Chart,实现了应用部署的标准化和可重复性。现在,无论是开发、测试还是生产环境,都可以用同样的方式部署应用。
-
弹性伸缩能力:借助HPA,应用可以根据实际负载自动扩缩容。流量高峰时自动扩容保障服务稳定,闲时自动缩容节省资源成本。
-
高可用保障:多副本部署配合Kubernetes的健康检查机制,确保了服务的高可用性。单个Pod故障不会影响整体服务。
-
简化运维:统一的配置管理、日志收集、监控告警,大大简化了运维工作。
11.2 实践经验总结
在实际部署过程中,有几个关键点需要特别注意:
- 资源规划要合理:GTE-large模型较大,需要足够的内存和CPU资源。建议生产环境至少分配8GB内存。
- 启动时间要预留:模型加载需要时间,务必配置合理的启动探针和初始延迟。
- 监控要到位:完善的监控是保障服务稳定的基础,特别是对内存使用率的监控。
- 渐进式发布:使用Helm的滚动更新功能,确保服务更新过程中不影响用户体验。
11.3 下一步建议
如果你已经成功部署了基础版本,可以考虑以下进阶优化:
-
多模型版本管理:使用Model Registry管理不同版本的模型,支持A/B测试和灰度发布。
-
请求路由优化:根据任务类型将请求路由到不同的Pod,实现更精细的资源管理。
-
缓存层添加:为频繁请求的结果添加Redis缓存,提升响应速度。
-
批量处理支持:优化API支持批量请求处理,提升吞吐量。
-
GPU支持:如果对推理速度有更高要求,可以考虑使用GPU节点。
11.4 最后的话
从单机脚本到云原生部署,这不仅仅是技术栈的升级,更是工程思维的转变。Kubernetes和Helm为我们提供了一套完整的应用生命周期管理方案,让像GTE-large这样的AI应用能够更稳定、更高效地服务于业务。
部署过程中可能会遇到各种问题,但每一步的解决都是经验的积累。记住,好的架构不是一蹴而就的,而是在不断迭代中逐渐完善的。希望本文能为你部署自己的AI应用提供有价值的参考。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐




所有评论(0)