Skip to content
共绩算力文档中心

怎么用云主机配置 LLM 环境并使用自动弹性扩缩容

在共绩算力云主机上搭建可弹性伸缩的 Qwen-7B-Chat 服务环境,实现:

  • 私有化部署大模型 API 服务
  • 根据流量自动扩缩容
  • 支持高并发访问

模型链接:https://huggingface.co/Qwen/Qwen-7B-Chat

Qwen-7B 是由阿里云提出的大型语言模型系列 Qwen(简称 Tongyi Qianwen)的 7B 参数版本。Qwen-7B 是一个基于 Transformer 的大型语言模型,预训练于大量数据,包括网页文本、书籍、代码等。此外,基于预训练的 Qwen-7B,我们发布了 Qwen-7B-Chat,一个基于大型模型的 AI 助手,采用对齐技术进行训练。现在我们已经更新了预训练和聊天模型,性能提升。

查看模型环境要求以及必要依赖项

登录共绩算力云主机,选择合适的云主机设备(大部分情况选择 4090 即可,如果需要先下载模型的情况。可以选择 CPU 启动 节省成本)

通过刚才的模型环境建议 选择适合的云主机框架环境

我们推荐在云主机中配置环境,存储模块中(对象存储加速中或者共享存储卷)放模型以达到镜像和模型的分离。

目前云主机磁盘限额 80GB,云主机磁盘内存过大会导致 关机/启动 时间过长

详细配置过程可以查看本文档底部附录一 附录二

  • 共享存储卷:主要用于高性能、高并发的读写场景。它像传统的硬盘或网络文件系统(如 NFS),可以被多个计算节点同时挂载,支持文件的频繁读写和修改,适合训练数据、模型中间结果、日志等需要频繁读写的场景。
  • 对象存储加速挂载:主要用于高效读取大规模数据,通常是只读场景。它将对象存储(如 S3)的数据通过挂载的方式直接呈现为本地文件系统,方便访问和读取,适合加载大数据集、预训练模型等只读需求。

通过共绩算力平台提供的 Web 终端或 Jupyter 终端登录,直接执行接下来的操作

如果需要使用 SSH 远程连接可以参考这篇文档:

https://www.gongjiyun.com/docs/server/jojuw4rfdiepfxkchonctw0jnxe/aanqw1zk3iedntkvqc6c6aapnkk/

清理旧环境(彻底消除冲突残留)

Terminal window
pip3 uninstall -y torch torchvision torchaudio vllm outlines xformers huggingface-hub openai
rm -rf /opt/miniconda3/lib/python3.12/site-packages/{torch*,vllm*,outlines*,xformers*,huggingface_hub*,openai*}
pip3 cache purge

安装核心依赖(从模型的说明文档中获取必要的配置信息 然后在云主机中进行安装)

Terminal window
pip3 install torch==2.7.1 torchvision==0.22.1 torchaudio==2.7.1 --index-url https://download.pytorch.org/whl/cu128 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install sentencepiece -i https://pypi.tuna.tsinghua.edu.cn/simple --only-binary :all:
pip3 install transformers==4.41.0 accelerate==0.31.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install modelscope==1.14.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

验证环境(确保无兼容问题)

执行以下命令,输出均符合预期则环境正常:

Terminal window
python3 -c "import torch; print('CUDA 可用:', torch.cuda.is_available()); print('GPU 型号:', torch.cuda.get_device_name(0)); print('PyTorch 版本:', torch.__version__)"
python3 -c "from transformers import AutoModelForCausalLM, AutoTokenizer; import modelscope; print('所有库导入成功')"

云主机启动成功后点击 查看详情——调试终端

推荐使用 ModelScope 国内镜像下载,避免 Hugging Face 官方源的网络问题,且自动下载完整配置文件(含 config.jsontokenizer.json 等):

Terminal window
cd /root/models/Qwen-7B-Chat
pip3 install tiktoken -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install transformers_stream_generator -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install modelscope fastapi uvicorn pydantic starlette python-multipart -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install --upgrade modelscope -i https://pypi.tuna.tsinghua.edu.cn/simple
apt update -y && apt install -y libgl1-mesa-glx
export MODEL_SCOPE_ENDPOINT=https://modelscope.cn/api/v1
modelscope download --model qwen/Qwen-7B-Chat --local-dir /root/models/Qwen-7B-Chat
cd /root/models/Qwen-7B-Chat
cat > download_ultimate.py << 'EOF'
from modelscope.hub.snapshot_download import snapshot_download
import os
os.makedirs(os.getcwd(), exist_ok=True)
try:
# 第 1 个参数:模型 ID,第 2 个参数:当前目录(/root/models/Qwen-7B-Chat)
model_dir = snapshot_download("qwen/Qwen-7B-Chat", os.getcwd())
print("\n🎉 模型下载成功!所有文件已保存到:", os.getcwd())
print("💡 立即启动交互:python3 /root/qwen_chat_stream_reset.py")
except Exception as e:
print("\n❌ 下载异常:", str(e))
print("🔧 自动重试(使用默认缓存目录)...")
model_dir = snapshot_download("qwen/Qwen-7B-Chat")
print(f"\n🎉 模型下载成功!默认路径:{model_dir}")
print("📥 正在自动复制到目标目录...")
os.system(f"cp -r {model_dir}/* {os.getcwd()}/")
print("✅ 复制完成!启动命令:python3 /root/qwen_chat_stream_reset.py")
EOF
export MODEL_SCOPE_ENDPOINT=https://modelscope.cn/api/v1 && python3 mxUpload.py

下载完成后执行以下命令,确保核心文件存在:

Terminal window
ls -l /root/models/Qwen-7B-Chat | grep -E "config.json|tokenizer.json|safetensors"

预期输出应包含:config.jsontokenizer.jsonmodel-00001-of-00002.safetensorsmodel-00002-of-00002.safetensors

3.4 非平台基础镜像如何配置 SSH 连接

Section titled “3.4 非平台基础镜像如何配置 SSH 连接”

可以参考这篇文档:https://www.gongjiyun.com/docs/server/jojuw4rfdiepfxkchonctw0jnxe/vkqcwyjz8i8yksknot6cia2fn0e/

4.编写 Python 启动脚本(控制台循环交互)

Section titled “4.编写 Python 启动脚本(控制台循环交互)”

https://huggingface.co/Qwen/Qwen-7B-Chat

从 huggingface 上看到快速使用调用模型脚本代码

创建 qwen_chat.py 脚本,代码无任何过时参数,适配当前依赖版本:

  • 首次启动:需编译 CUDA 内核,耗时约 5-10 分钟,耐心等待即可;
  • 后续启动:直接加载缓存,耗时 1-2 分钟。
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
MODEL_PATH = "/root/models/Qwen-7B-Chat"
def load_model():
"""加载模型和 Tokenizer,仅初始化一次"""
print("正在加载 Qwen-7B-Chat 模型...(首次启动较慢,约 5-10 分钟,请耐心等待)")
# 加载 Tokenizer(适配 Qwen 模型格式)
tokenizer = AutoTokenizer.from_pretrained(
MODEL_PATH,
trust_remote_code=True,
padding_side="right", # 右侧填充,避免生成错误
truncation=True
)
# 加载模型(自动适配 RTX 5090 GPU)
model = AutoModelForCausalLM.from_pretrained(
MODEL_PATH,
trust_remote_code=True,
device_map="auto", # 自动分配 GPU/CPU,优先使用 RTX 5090
torch_dtype=torch.float16, # 显存优化,32GB GPU 足够运行
load_in_8bit=False, # 不量化,保证生成效果
low_cpu_mem_usage=True # 降低 CPU 内存占用
).eval() # 推理模式,禁用 Dropout 确保结果稳定
print("\n✅ 模型加载完成!输入 'quit' 退出对话,输入提示词即可开始交互~")
return tokenizer, model
def chat_loop(tokenizer, model):
"""控制台循环交互"""
while True:
prompt = input("\n请输入提示词:")
if prompt.lower().strip() == "quit":
print("👋 退出对话,感谢使用!")
break
if not prompt.strip():
print("❌ 提示词不能为空,请重新输入~")
continue
# 构建输入(适配 Qwen 模型的 Prompt 格式)
inputs = tokenizer(
prompt,
return_tensors="pt",
truncation=True,
max_length=8192 # 匹配 Qwen 模型最大序列长度
).to(model.device)
# 生成回答(无梯度计算,节省显存)
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=1024, # 最大生成 1024 个字符
temperature=0.7, # 随机性:0-1,值越大越灵活
top_p=0.95, # 采样阈值:过滤低概率词汇
do_sample=True, # 启用采样生成
eos_token_id=tokenizer.eos_token_id, # 结束标记
pad_token_id=tokenizer.pad_token_id, # 填充标记
repetition_penalty=1.1 # 重复惩罚,减少废话
)
# 解码并提取回答(去除输入提示词)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
response = response.replace(prompt, "").strip()
# 打印结果
print(f"\n📢 模型回答:\n{response}")
if __name__ == "__main__":
try:
tokenizer, model = load_model()
chat_loop(tokenizer, model)
except Exception as e:
print(f"\n❌ 运行出错:{str(e)}")
print("请检查:1. 模型文件是否完整;2. 依赖包是否安装正确;3. 显存是否充足")

运行脚本

python3 /root/qwen_chat.py
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
MODEL_PATH = "/root/models/Qwen-7B-Chat"(如果使用平台共享存储卷存储模型文件就用<b>共享存储卷的路径</b>来下载存储模型文件)
def load_model():
"""加载模型和 Tokenizer,仅初始化一次"""
print("正在加载 Qwen-7B-Chat 模型...(首次启动较慢,约 5-10 分钟,请耐心等待)")
# 加载 Tokenizer(适配 Qwen 模型格式)
tokenizer = AutoTokenizer.from_pretrained(
MODEL_PATH,
trust_remote_code=True,
padding_side="right", # 右侧填充,避免生成错误
truncation=True
)
# 加载模型(自动适配 RTX 5090 GPU)
model = AutoModelForCausalLM.from_pretrained(
MODEL_PATH,
trust_remote_code=True,
device_map="auto", # 自动分配 GPU/CPU,优先使用 RTX 5090
torch_dtype=torch.float16, # 显存优化,32GB GPU 足够运行
load_in_8bit=False, # 不量化,保证生成效果
low_cpu_mem_usage=True # 降低 CPU 内存占用
).eval() # 推理模式,禁用 Dropout 确保结果稳定
print("\n✅ 模型加载完成!输入 'quit' 退出对话,输入提示词即可开始交互~")
return tokenizer, model
def chat_loop(tokenizer, model):
"""控制台循环交互"""
while True:
prompt = input("\n请输入提示词:")
if prompt.lower().strip() == "quit":
print("👋 退出对话,感谢使用!")
break
if not prompt.strip():
print("❌ 提示词不能为空,请重新输入~")
continue
# 构建输入(适配 Qwen 模型的 Prompt 格式)
inputs = tokenizer(
prompt,
return_tensors="pt",
truncation=True,
max_length=8192 # 匹配 Qwen 模型最大序列长度
).to(model.device)
# 生成回答(无梯度计算,节省显存)
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=1024, # 最大生成 1024 个字符
temperature=0.7, # 随机性:0-1,值越大越灵活
top_p=0.95, # 采样阈值:过滤低概率词汇
do_sample=True, # 启用采样生成
eos_token_id=tokenizer.eos_token_id, # 结束标记
pad_token_id=tokenizer.pad_token_id, # 填充标记
repetition_penalty=1.1 # 重复惩罚,减少废话
)
# 解码并提取回答(去除输入提示词)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
response = response.replace(prompt, "").strip()
# 打印结果
print(f"\n📢 模型回答:\n{response}")
if __name__ == "__main__":
try:
tokenizer, model = load_model()
chat_loop(tokenizer, model)
except Exception as e:
print(f"\n❌ 运行出错:{str(e)}")
print("请检查:1. 模型文件是否完整;2. 依赖包是否安装正确;3. 显存是否充足")

交互示例:

正在加载 Qwen-7B-Chat 模型...(首次启动较慢,约 5-10 分钟,请耐心等待)
✅ 模型加载完成!输入 'quit' 退出对话,输入提示词即可开始交互~
请输入提示词:介绍一下自己
📢 模型回答:
我是 Qwen-7B-Chat 大模型,基于 Transformer 架构训练而成,支持多轮对话、信息查询、创意生成等多种功能。我具备较强的语言理解和生成能力,能够根据你的需求提供准确、流畅的回答,适用于日常交流、学习辅助、工作协作等场景~
请输入提示词:quit
👋 退出对话,感谢使用!

6.本地调用(远程访问云主机模型)

Section titled “6.本地调用(远程访问云主机模型)”

若需从本地电脑调用云主机上的模型,可在云主机上通过 FastAPI 搭建简单 API 服务:

  1. 安装 API 依赖
Terminal window
pip3 install fastapi uvicorn pydantic -i https://pypi.tuna.tsinghua.edu.cn/simple
  1. 创建 API 服务脚本 qwen_api.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
app = FastAPI(title="Qwen-7B-Chat API")
MODEL_PATH = "/root/models/Qwen-7B-Chat"
tokenizer, model = None, None
@app.on_event("startup")
def startup():
global tokenizer, model
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
MODEL_PATH, trust_remote_code=True, device_map="auto", torch_dtype=torch.float16
).eval()
class PromptRequest(BaseModel):
prompt: str
@app.post("/generate")
async def generate(request: PromptRequest):
try:
inputs = tokenizer(request.prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(**inputs, max_new_tokens=1024, temperature=0.7, top_p=0.95)
response = tokenizer.decode(outputs[0], skip_special_tokens=True).replace(request.prompt, "").strip()
return {"prompt": request.prompt, "response": response}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
import uvicorn
# 允许外部访问(云主机公网 IP 可访问)
uvicorn.run(app, host="0.0.0.0", port=8000)
  1. 启动 API 服务
Terminal window
nohup python3 /root/qwen_api.py > qwen_api.log 2>&1
  1. 本地电脑调用脚本 local_client.py
import requests
API_URL = "https://云主机公网 IP:8000/generate(任务暴露的公网映射地址链接)"
def call_qwen(prompt):
try:
response = requests.post(API_URL, json={"prompt": prompt}, timeout=60)
if response.status_code == 200:
return response.json()["response"]
else:
return f"调用失败:{response.text}"
except Exception as e:
return f"网络错误:{str(e)}"
if __name__ == "__main__":
while True:
prompt = input("请输入提示词(输入'quit'退出):")
if prompt.lower() == "quit":
break
result = call_qwen(prompt)
print(f"\n模型回答:\n{result}\n")

7.如何转换为弹性部署服务(自动弹性扩缩容)

Section titled “7.如何转换为弹性部署服务(自动弹性扩缩容)”

若您的业务流量存在明显波动或需要按需使用资源以控制成本,强烈建议启用自动扩缩容功能。按需分配资源,避免资源浪费,确保任务稳定运行,提升效率并降低长时间占用成本。

  1. 回到云主机页面,找到“部署服务”
  1. 关机并保存镜像,输入镜像标签
  1. 选择最新版本
  1. 选择 GPU 配置(如 4090),节点默认选择 1 个
  1. 挂载存储卷

注意:挂载存储的时候,不要直接挂载到/、/root、 /root/目录,否则会出现一些奇怪的问题。建议挂载在类似/root/data、/root/code 之类的二级目录。

其他配置根据自己镜像的需要来进行配置

  1. 点击最下方“确认部署”即可,若无问题则会进入节点拉取界面,耐心等待即可

具体的自动弹性扩缩容设置可以参考这篇使用文档:https://www.gongjiyun.com/docs/y/nnnkwiwlkid3m1ksgxdcrvsknrj/jurlwpstdiyokzkzwqocfpclnbf/

参数设置建议

最小节点数:建议设置为 1,避免冷启动影响。如果业务对响应时间要求极高,可以适当增加。

最大节点数:根据预算和业务峰值合理设置。建议先从小值开始,观察实际使用情况后逐步调整。

队列延迟阈值:建议设置为 4-10 秒,平衡成本和体验。对于实时性要求高的任务,可以设置较小值。

空闲超时时间:建议设置为 300-600 秒,减少冷启动影响的同时控制成本。

附录 1 对象存储加速中放置模型

Section titled “附录 1 对象存储加速中放置模型”

点击”新增对象存储配置”按钮,选择云服务商,填写以下信息:

  • 配置名称
  • 对象存储:服务商、地域、Endpoint(不能带 Bucket)、AccessKey、SecretKey、Bucket 名称
  • 加速目录:Bucket 中需进行加速处理的目录(不建议挂载根目录,因这会致使根目录下所有文件被缓存,占用大量空间,且不利于业务的合理分割)

当执行保存配置操作时,系统会自动对配置的可用性进行检测。只有在校验通过之后,配置才可成功保存。在列表中查找到相应配置后,点击“开始加速”选项,接着选择加速区域,此时系统将自动对 JuiceFS 文件系统进行初始化(此过程约需 1 - 2 分钟,期间状态会从蓝色转变为绿色,状态为绿色时已可以挂载此存储桶)。同时,系统还会执行提前预热操作(此操作需从云端将文件下载至本地,因此需等待一定时长。例如,若文件大小为 6.6 G,下载完成大约需要 30 分钟)。

任务发布时挂载

先选择 GPU、GPU 区域(需要与对象存储选择的加速区域一致)。我的对象存储加速了“浙江一区”,所以我选择“浙江一区”的 4090 GPU。

然后在任务发布页面的”存储配置”区域,选择已配置并加速的 S3 存储桶(当前状态为绿色时,可以直接挂载。集群内第一次使用需要等待从云端拉取文件到集群。此操作需从云端将文件下载至本地,因此需等待一定时长。例如,若文件大小为 6.6 G,下载完成大约需要 30 分钟。集群第二次挂载则会直接从本地拉取模型文件)。

为每个对象存储加速目录填写容器内的挂载路径(如 /mnt/my_model_data),路径需以 / 开头。需要注意两个目录的对应关系。

我这里将对象存储 Bucket 中的 /qwen1-5/hub/挂载到了容器中的 /root/.cache/huggingface 目录中

提交任务后,容器启动时会自动挂载所选 S3 存储。待容器启动完成后,可进入容器并验证挂载。查看挂载目录下的文件是否存在

详细配置细节可以参考对象存储加速文档

创建新的存储桶:

重要提醒:

• 存储桶共享 200.0 GBGB 总容量,可创建多个存储桶

• 单区域桶无流量传输费用,多区域桶会产生区域间同步费用

• 某地区未使用节点 15 天后,缓存组将被自动释放

• 多实例同时读写可能存在短暂延迟,但保证最终一致性

• 建议定期使用存储桶以避免节点释放影响

配置完成后输入挂载路径

在 jupyterlab 中将模型相关配置下载在挂载路径中(例如 /root/data)以实现多机数据共享 达到镜像和模型的分离