【202603更新】记录大模型推理服务部署和使用过程中的一些资源,包括但不限于部署环境、部署框架常用优化、模型调用、多模态对话模型、多模态向量模型等(非特殊说明,均为Linux环境、Nvidia显卡)
模型部署环境
-
Nvidia显卡、Docker部署环境:Ubuntu Nvidia Docker单机多卡环境配置
-
CUDA安装与更新:cuda 历史发布版本及安装、cuda版本与显卡驱动对应关系
- CUDA卸载
apt-get --purge remove "*cuda*" "*cublas*" "*cufft*" "*curand*" "*cusolver*" "*cusparse*" "*npp*" "*nvjpeg*" "nsight*" "nvidia-cuda-toolkit" apt-get autoremove - CUDA安装
chmod +x cuda_13.0.0_580.65.06_linux.run sudo ./cuda_13.0.0_580.65.06_linux.run \ --toolkit \ --silent \ --override \ --no-drm \ --no-man-page \ --toolkitpath=/usr/local/cuda-13.0 - CUDA安装确认
注意: 如果需要是用NVIDIA Docker,还需要重新配置,安装可参考第一条Nvidia、Docker部署环境里面的内容# 检查安装 nvcc --version # 应显示 13.0 nvidia-smi # 查看GPU状态 ls -la /usr/local/cuda # 确认软链接
- CUDA卸载
-
Nvidia安装与更新:Nvida各显卡驱动下载,安装可参考第一条Nvidia、Docker部署环境里面的内容
模型下载&服务
模型下载
- 国内外常用的模型下载平台
- Modelscope,阿里维护,活跃度高,模型覆盖度高且范围广,国内首推使用
下载方式:推荐git lfs下载方式,大文件下载友好,模型库搜到相关模型,点击进去偏右上角‘下载模型’ 首推下载方式,git lfs + nohup 比如下载qwen3-vl-8B-instruct模型: 第一步:GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/Qwen/Qwen3-VL-8B-Instruct.git 第二步:进入Qwen3-VL-8B-Instruct目录,先执行:git lfs pull --include='*.json',下载配置文件 第三步:下载模型权重文件,可使用nohup命令,也可不使用,不使用的命令: git lfs pull --inlcude='*.safetensors' - Hugginface,世界级更新,国内外一些不常见模型在此均能找到,国内访问&下载受限
- Modelscope,阿里维护,活跃度高,模型覆盖度高且范围广,国内首推使用
模型服务
- 阿里百炼平台上的模型列表: 百炼模型广场
- Deepseek官网模型调用:Deepseek开发平台
- 智谱大模型调用:智谱AI开发平台-模型广场
其他比如百度千问、字节豆包-火山引擎、腾讯混元、minimax、月之暗面等可自行查阅。
模型部署(vLLM)
注意文本模型和多模态模型部署存在一定差距,大部分参数都相同,但有自己独特参数,建议多看vLLM官方文档
-
文本模型部署示例(http版,https版不记录,指定GPU编号:–gpus ‘“device=0,1,2,3”’)
docker run -d --runtime nvidia --gpus 4 --ipc=host -p 8000:8000 -v /root:/root --name=ds_r1_32b vllm vllm-openai:v0.11.0 --model /root/models/ds_r1_32b -instruct --trust-remote-code --served-model-name ds_r1_32b --max_num_seqs 128 --tensor-parallel-size 4 --gpu_memory_utilization 0.95 --no-enforce-eager --disable-custom-all-reduce --compilation-config '{"level": 3, "cudagraph_capture_sizes": [1, 5, 20]}' --enable-prefix-caching --enable-chunked-prefill --rope-scaling '{"rope_type":"yarn","factor":4.0,"original_max_position_embeddings":32768}' --max-model-len 131072 --reasoning-parser deepseek_r1 --enable-auto-tool-choice --tool-call-parser hermes -
多模态模型部署示例(Qwen3.5-27b-FP8示例)
docker run -d --runtime nvidia --gpus all --ipc=host -p 8000:8000 -v /root/models:/root/models --env TRANSFORMERS_OFFLINE=0 --env HF_HUB_OFFLINE=1 --env PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128 --env PYTORCH_ALLOC_CONF=expandable_segments:True --env VLLM_USE_FLASHINFER_SAMPLER=1 --env VLLM_MARLIN_USE_ATOMIC_ADD=1 --env OMP_NUM_THREADS=2 --env VLLM_SLEEP_WHEN_IDLE=1 --volume /lib/x86_64-linux-gnu/libjemalloc.so.2:/opt/lib/libjemalloc.so.2:ro --env LD_PRELOAD="/opt/lib/libjemalloc.so.2" --name=qwen3.5-27b vllm/vllm-openai:nightly --model /root/models/Qwen3.5-27B-FP8 --trust-remote-code --served-model-name qwen3.5-27b --max_num_seqs 5 --tensor-parallel-size 4 --gpu_memory_utilization 0.95 --no-enforce-eager --disable-custom-all-reduce --compilation-config '{"cudagraph_mode": "FULL_AND_PIECEWISE"}' --enable-prefix-caching --enable-chunked-prefill --max-model-len 262144 --reasoning-parser qwen3 --speculative-config '{"method":"mtp","num_speculative_tokens":2}' --mamba-cache-mode align --limit-mm-per-prompt '{"video": 0, "image":256}' --mm-encoder-attn-backend TORCH_SDPA --enable-auto-tool-choice --tool-call-parser qwen3_coder --max-num-batched-tokens 4092 --async-scheduling --attention-config.backend FLASHINFER --enable-log-requests -
多模态向量模型部署示例(示例是qwen3-vl-embedding-2B模型,vllm >=0.14.x)
docker run -d --runtime nvidia --gpus 1 --ipc=host -p 8000:8000 -v /root/models:/root/models --name=qwen3-vl-embd vllm/vllm-openai:v0.14.0-cu130 --model /root/models/Qwen3-VL-Embedding --trust-remote-code --served-model-name qwen3-vl-embd --max_num_seqs 20 --tensor-parallel-size 1 --gpu_memory_utilization 0.5 --enforce-eager --disable-custom-all-reduce --compilation-config '{"level": 0}' --enable-prefix-caching --enable-chunked-prefill --max-model-len 32000 --runner pooling
模型访问
-
文本大模型访问:首推OpenAI SDK调用大模型服务,下面是一个示例,注意后面的备注:
from openai import OpenAI API_KEY=xxx BASE_URL=xxx MODEL_NAME=xxx client = OpenAI( api_key=API_KEY, base_url=BASE_URL, ) instruct = "今天天气怎么样" response = client.chat.completions.create( model=MODEL_NAME, messages=[ {"role": "user", "content": instruct } ], temperature=0.01, max_tokens=2048, ) print(response) print(response.choices[0].message.content) print(f"【usage】: {response.usage}")注意:
- 控制qwen模型的思考模式:
extra_body={"chat_template_kwargs": {"enable_thinking": False}} - 控制gpt-oss模型的思考模式:
extra_body={"reasoning_effort": "low"}
- 控制qwen模型的思考模式:
-
多模态大模型访问(本地图片)
from openai import OpenAI import os import base64 # 初始化OpenAI客户端 client = OpenAI( api_key = "xxx", base_url="http://127.0.0.1:8000/v1" ) # 编码函数: 将本地文件转换为 Base64 编码的字符串 def encode_image(image_path): with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode("utf-8") prompt = r"分析这张图片,对它的内容进行描述,不超过200字" image_url = r"docs/image_parse_test.png" completion = client.chat.completions.create( model="qwen3-vl-32b", messages=[ { "role": "user", "content": [ { "type": "image_url", # 需要注意,传入Base64,图像格式(即image/{format})需要与支持的图片列表中的Content Type保持一致。"f"是字符串格式化的方法。 # PNG图像: f"data:image/png;base64,{base64_image}" # JPEG图像: f"data:image/jpeg;base64,{base64_image}" # WEBP图像: f"data:image/webp;base64,{base64_image}" "image_url": {"url": f"data:image/png;base64,{encode_image(image_url)}"}, }, {"type": "text", "text": prompt}, ], } ], # extra_body={"vl_high_resolution_images":True} ) print(completion) print(f"耗时:{time.time() - start}\n") print(completion.choices[0].message.content) -
多模态向量模型访问(Qwen3-vl-embedding,vLLM 在线部署,本地图片)
from PIL import Image import requests import base64 API_URL = "http://127.0.0.1:8000/v1/embeddings" MODEL = "qwen3-vl-embd" def get_multimodal_embedding( text: str = None, image_path: str = None, # 本地 image url途径,在线的访问可google一下 instruction: str = "Represent the query for retrieval:" # 可自定义,如 retrieval 任务用 "Represent the query for retrieval:" ): # 构建 user content content = [] img_url = None if image_path: with open(image_path, "rb") as img_file: # 方式一 base64_img = base64.b64encode(img_file.read()).decode("utf-8") img_url = f"data:image/png;base64,{base64_img}" # 方式二 # img = Image.open(image_path).convert("RGB") # buf = io.BytesIO() # img.save(buf, format="png", quality=90) # b64 = base64.b64encode(buf.getvalue()).decode("utf-8") # img_url = f"data:image/png;base64,{b64}" if img_url: content.append({"type": "image_url", "image_url": {"url": img_url}}) if text: content.append({"type": "text", "text": text}) if not content: return None # 完整 messages messages = [ {"role": "system", "content": [{"type": "text", "text": instruction}]}, {"role": "user", "content": content}, {"role": "assistant", "content": [{"type": "text", "text": ""}]} # 必加 ] payload = { "model": MODEL, "messages": messages, "encoding_format": "float", # 或 "base64" 返回字符串 "continue_final_message": True, "add_special_tokens": True } response = requests.post(API_URL, json=payload) response.raise_for_status() data = response.json() embedding = data["data"][0]["embedding"] return embedding # 测试示例 image_paths = [ "mm_embd_demo.jpg" ] # 计算所有本地图片的纯图片 embedding image_embeddings = [] for path in image_paths: emb = get_multimodal_embedding(image_path=path, text='') image_embeddings.append(emb) print(len(image_embeddings))

1039

被折叠的 条评论
为什么被折叠?



