GLM-4V-9B开源模型部署教程:Ubuntu+NVIDIA驱动+Conda环境全链路配置

1. 环境准备与系统要求

在开始部署GLM-4V-9B模型之前,我们需要确保系统环境满足基本要求。这个多模态大模型对硬件和软件都有特定需求,特别是对显卡和内存的要求较高。

最低系统配置要求

  • 操作系统:Ubuntu 18.04或更高版本
  • 显卡:NVIDIA RTX 3090或更高(至少24GB显存)
  • 内存:32GB RAM或更高
  • 存储:至少50GB可用空间(用于模型文件和依赖包)

推荐配置

  • 操作系统:Ubuntu 20.04 LTS
  • 显卡:NVIDIA RTX 4090(24GB显存)
  • 内存:64GB RAM
  • 存储:100GB SSD空间

如果你使用的是消费级显卡(如RTX 3080 10GB),通过4-bit量化技术也可以运行,但可能会在生成高分辨率图像时遇到显存限制。

2. NVIDIA驱动与CUDA安装

正确的NVIDIA驱动和CUDA环境是模型运行的基础。以下是详细的安装步骤:

2.1 安装NVIDIA驱动

首先更新系统包列表并安装基础工具:

sudo apt update
sudo apt upgrade -y
sudo apt install build-essential dkms -y

添加NVIDIA官方驱动仓库:

# 添加NVIDIA包仓库
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update

# 查找推荐的驱动版本
ubuntu-drivers devices

# 安装推荐驱动(通常是最新版本)
sudo apt install nvidia-driver-535 -y

# 重启系统使驱动生效
sudo reboot

重启后验证驱动安装:

nvidia-smi

你应该看到类似这样的输出,显示显卡信息和驱动版本:

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 535.104.05   Driver Version: 535.104.05   CUDA Version: 12.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  On   | 00000000:01:00.0  On |                  N/A |
|  0%   48C    P8    22W / 350W |    689MiB / 24576MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

2.2 安装CUDA Toolkit

接下来安装CUDA工具包,这是PyTorch运行的基础:

# 下载并安装CUDA 12.2
wget https://developer.download.nvidia.com/compute/cuda/12.2.2/local_installers/cuda_12.2.2_535.104.05_linux.run
sudo sh cuda_12.2.2_535.104.05_linux.run

在安装过程中,确保选择以下组件:

  • [X] CUDA Toolkit 12.2
  • [ ] CUDA Documentation
  • [ ] CUDA Samples
  • [X] Driver(如果尚未安装最新驱动)

配置环境变量:

# 编辑bashrc文件
echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc

验证CUDA安装:

nvcc --version

2.3 安装cuDNN

cuDNN是NVIDIA的深度神经网络库,能显著加速模型推理:

# 需要先注册NVIDIA开发者账号并下载cuDNN
# 下载后解压并复制文件
tar -xvf cudnn-linux-x86_64-8.9.4.25_cuda12-archive.tar.xz
sudo cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda/include 
sudo cp -P cudnn-*-archive/lib/libcudnn* /usr/local/cuda/lib64 
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*

3. Conda环境配置

使用Conda创建独立的Python环境可以避免依赖冲突,下面是详细步骤:

3.1 安装Miniconda

首先下载并安装Miniconda:

# 下载Miniconda安装脚本
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh

# 运行安装脚本
bash Miniconda3-latest-Linux-x86_64.sh

# 按照提示完成安装,通常选择默认选项即可
# 安装完成后激活conda
source ~/.bashrc

3.2 创建专用环境

为GLM-4V-9B创建独立的Python环境:

# 创建名为glm4v的环境,指定Python 3.10
conda create -n glm4v python=3.10 -y

# 激活环境
conda activate glm4v

3.3 安装PyTorch与依赖

安装与CUDA 12.2兼容的PyTorch版本:

# 安装PyTorch和相关依赖
pip install torch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 --index-url https://download.pytorch.org/whl/cu121

# 安装其他必要依赖
pip install transformers==4.36.0 streamlit==1.28.0 Pillow==10.0.0 accelerate==0.25.0

4. GLM-4V-9B模型部署

现在开始部署GLM-4V-9B模型,这是最关键的步骤。

4.1 下载项目代码

克隆项目仓库并安装特定依赖:

# 克隆项目代码
git clone https://github.com/THUDM/GLM-4V-9B.git
cd GLM-4V-9B

# 安装项目特定依赖
pip install -r requirements.txt

# 额外安装bitsandbytes用于4-bit量化
pip install bitsandbytes==0.41.3

4.2 模型下载与配置

GLM-4V-9B模型文件较大,需要从Hugging Face下载:

# 使用git lfs下载模型(需要先安装git-lfs)
sudo apt install git-lfs
git lfs install

# 克隆模型仓库(约18GB)
git clone https://huggingface.co/THUDM/glm-4v-9b

如果网络条件不好,也可以使用huggingface-hub库下载:

from huggingface_hub import snapshot_download

snapshot_download(
    repo_id="THUDM/glm-4v-9b",
    local_dir="./glm-4v-9b",
    ignore_patterns=["*.msgpack", "*.h5", "*.ot"]
)

4.3 配置4-bit量化

为了在消费级显卡上运行,我们需要配置4-bit量化:

# 创建模型加载脚本 model_loader.py
import torch
from transformers import AutoModel, AutoTokenizer

# 配置4-bit量化
model = AutoModel.from_pretrained(
    "./glm-4v-9b",
    torch_dtype=torch.float16,
    device_map="auto",
    load_in_4bit=True,  # 启用4-bit量化
    trust_remote_code=True
)

tokenizer = AutoTokenizer.from_pretrained(
    "./glm-4v-9b", 
    trust_remote_code=True
)

5. 解决兼容性问题

GLM-4V-9B在特定环境下可能会遇到兼容性问题,以下是解决方案:

5.1 数据类型冲突解决

原版代码可能存在数据类型冲突,需要动态适配:

# 动态检测视觉层数据类型,防止手动指定float16导致与环境bfloat16冲突
try:
    visual_dtype = next(model.transformer.vision.parameters()).dtype
except:
    visual_dtype = torch.float16

# 强制转换输入图片Tensor类型
def process_image(image_path):
    from PIL import Image
    import torchvision.transforms as transforms
    
    # 加载图像
    image = Image.open(image_path).convert('RGB')
    
    # 图像预处理
    preprocess = transforms.Compose([
        transforms.Resize((224, 224)),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.48145466, 0.4578275, 0.40821073], 
                           std=[0.26862954, 0.26130258, 0.27577711])
    ])
    
    image_tensor = preprocess(image).unsqueeze(0)
    
    # 转换为正确的数据类型和设备
    image_tensor = image_tensor.to(device=model.device, dtype=visual_dtype)
    
    return image_tensor

5.2 Prompt顺序修正

修正官方Demo中的Prompt顺序问题,确保模型正确理解指令:

def build_prompt(user_input, image_tensor):
    """
    构建正确的Prompt顺序:User -> Image -> Text
    避免模型把图片误判为系统背景图
    """
    # 用户指令部分
    user_ids = tokenizer.encode(user_input, return_tensors="pt").to(model.device)
    
    # 图像标记部分
    image_token_ids = tokenizer.encode("<image>", return_tensors="pt").to(model.device)
    
    # 文本结束标记
    text_ids = tokenizer.encode("\n", return_tensors="pt").to(model.device)
    
    # 正确的拼接顺序
    input_ids = torch.cat((user_ids, image_token_ids, text_ids), dim=1)
    
    return input_ids

6. Streamlit界面部署

Streamlit提供了友好的Web界面,让用户可以轻松与模型交互。

6.1 创建Streamlit应用

创建主要的应用文件:

# app.py
import streamlit as st
import torch
from PIL import Image
import os
from model_loader import load_model_tokenizer

# 设置页面标题和图标
st.set_page_config(
    page_title="GLM-4V-9B 多模态对话",
    page_icon="🦅",
    layout="wide"
)

# 初始化session state
if "model" not in st.session_state:
    with st.spinner("正在加载模型,请稍候..."):
        st.session_state.model, st.session_state.tokenizer = load_model_tokenizer()

if "messages" not in st.session_state:
    st.session_state.messages = []

# 侧边栏设置
with st.sidebar:
    st.title("GLM-4V-9B 设置")
    
    # 图片上传
    uploaded_file = st.file_uploader(
        "上传图片", 
        type=["jpg", "jpeg", "png"],
        help="支持JPG、PNG格式的图片"
    )
    
    # 清除对话按钮
    if st.button("清除对话历史"):
        st.session_state.messages = []
        st.rerun()

# 显示对话历史
for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        if message["type"] == "text":
            st.markdown(message["content"])
        elif message["type"] == "image":
            st.image(message["content"], use_column_width=True)

# 用户输入
if prompt := st.chat_input("请输入您的问题..."):
    # 添加用户消息到历史
    st.session_state.messages.append({
        "role": "user", 
        "content": prompt, 
        "type": "text"
    })
    
    # 显示用户消息
    with st.chat_message("user"):
        st.markdown(prompt)
    
    # 生成回复
    with st.chat_message("assistant"):
        with st.spinner("思考中..."):
            try:
                # 处理图片和生成回复
                if uploaded_file is not None:
                    # 保存上传的图片
                    image_path = f"temp_{uploaded_file.name}"
                    with open(image_path, "wb") as f:
                        f.write(uploaded_file.getbuffer())
                    
                    # 处理图片并生成回复
                    response = generate_response(
                        prompt, 
                        image_path, 
                        st.session_state.model, 
                        st.session_state.tokenizer
                    )
                    
                    # 显示图片
                    st.image(image_path, caption="上传的图片", use_column_width=True)
                    
                    # 清理临时文件
                    os.remove(image_path)
                else:
                    response = generate_response(
                        prompt, 
                        None, 
                        st.session_state.model, 
                        st.session_state.tokenizer
                    )
                
                # 显示助手回复
                st.markdown(response)
                
                # 添加助手消息到历史
                st.session_state.messages.append({
                    "role": "assistant", 
                    "content": response, 
                    "type": "text"
                })
                
            except Exception as e:
                st.error(f"生成回复时出错: {str(e)}")

6.2 启动Streamlit服务

创建启动脚本:

# run.sh
#!/bin/bash

# 激活conda环境
conda activate glm4v

# 启动streamlit服务
streamlit run app.py --server.port=8080 --server.address=0.0.0.0

给脚本添加执行权限并运行:

chmod +x run.sh
./run.sh

现在你可以在浏览器中访问 http://你的服务器IP:8080 来使用GLM-4V-9B多模态对话系统了。

7. 常见问题与解决方案

在部署过程中可能会遇到一些问题,以下是常见问题的解决方案:

7.1 显存不足问题

如果遇到显存不足的错误,可以尝试以下解决方案:

# 进一步降低精度或使用内存卸载
model = AutoModel.from_pretrained(
    "./glm-4v-9b",
    torch_dtype=torch.float16,
    device_map="auto",
    load_in_4bit=True,
    low_cpu_mem_usage=True,  # 降低CPU内存使用
    trust_remote_code=True
)

7.2 模型加载失败

如果模型加载失败,检查文件完整性:

# 检查模型文件完整性
cd glm-4v-9b
ls -la

# 应该看到类似这样的文件结构:
# config.json  model.safetensors  tokenizer.json  tokenizer_config.json

7.3 端口被占用

如果8080端口被占用,可以更改端口号:

# 更改启动端口
streamlit run app.py --server.port=8081 --server.address=0.0.0.0

8. 总结

通过本教程,我们完成了GLM-4V-9B多模态大模型在Ubuntu系统上的完整部署流程。从NVIDIA驱动安装、CUDA环境配置,到Conda环境搭建和模型部署,每一步都提供了详细的指导和代码示例。

关键成功要素

  1. 正确的NVIDIA驱动和CUDA版本匹配
  2. 使用Conda创建独立的Python环境避免依赖冲突
  3. 4-bit量化技术让消费级显卡也能运行大模型
  4. 动态类型适配解决了环境兼容性问题
  5. 正确的Prompt顺序确保模型理解用户意图

现在你已经拥有了一个功能完整的多模态AI对话系统,可以处理图像和文本输入,生成智能回复。你可以进一步探索模型的其他功能,或者基于这个基础开发更复杂的应用。

获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐