GLM-4v-9b图文对话教程:支持标记注入,兼容LlamaIndex多模态RAG

你是不是经常遇到这种情况:拿到一张复杂的图表,想快速理解里面的数据趋势;或者看到一张产品截图,想让它帮你分析里面的功能点。以前,你可能需要自己看图、读文字、再手动整理信息,费时费力。

现在,有了GLM-4v-9b,事情就简单多了。这是一个能同时看懂图片和文字的多模态模型,你只需要把图片丢给它,然后用自然语言提问,它就能给你详细的回答。更棒的是,它原生支持高分辨率图片,表格里的小字、图表里的细节都能看得清清楚楚。

今天这篇教程,我就带你从零开始,快速部署GLM-4v-9b,并上手体验它的核心功能——图文对话。我们还会探索一个进阶玩法:如何利用它支持的<image>标记注入功能,与LlamaIndex框架结合,构建你自己的多模态RAG(检索增强生成)应用,让AI不仅能看图说话,还能从你的专属知识库中寻找答案。

学完这篇教程,你将能:

  1. 在个人电脑或服务器上,一键部署并启动GLM-4v-9b服务。
  2. 掌握与模型进行图文对话的基本方法和技巧。
  3. 理解并初步实践如何将GLM-4v-9b接入LlamaIndex,构建一个简单的多模态RAG原型。

1. 快速认识GLM-4v-9b:你的全能图文助手

在动手之前,我们先花几分钟了解一下这位“新同事”到底有什么本事,这样用起来会更得心应手。

简单来说,GLM-4v-9b是智谱AI在2024年开源的一个视觉-语言模型。它有90亿参数,这个规模让它既保持了强大的理解能力,又对硬件比较友好。它的核心能力就是“图文兼修”:既能处理你输入的文字问题,也能深度理解你上传的图片内容,然后给出综合性的回答。

它有几个特别突出的优点,正是这些优点让它从众多模型中脱颖而出:

  • 看得清:它原生支持高达1120×1120分辨率的高清图片输入。这意味着图表中的坐标轴小字、网页截图里的密集文字、复杂流程图中的连线,它都能较好地捕捉和识别,不会因为图片压缩而丢失关键信息。
  • 聊得来:它在中文和英文的多轮对话上都做了专门优化。你可以就同一张图片,连续追问多个问题,它能结合上下文给出连贯的回答。特别是在中文场景下的OCR(文字识别)和图表理解任务中,它的表现非常亮眼。
  • 跑得动:模型对硬件要求相对亲民。全精度(fp16)模型大约需要18GB显存,而经过INT4量化后,显存需求可以降到9GB左右。这意味着拥有一张RTX 4090(24GB显存)显卡,你就能流畅地进行全速推理。这对于个人开发者和小型团队来说,是一个巨大的利好。
  • 用得起:它采用了开放的开源协议。代码是Apache 2.0,权重是OpenRAIL-M协议。对于年营收在一定规模以下的初创公司,甚至可以免费商用,极大地降低了技术尝试和产品集成的门槛。

一句话总结:如果你需要一个大模型来帮你处理中文图表、分析截图内容,并且希望它能在单张消费级显卡上流畅运行,那么GLM-4v-9b是一个非常直接且高效的选择。

2. 环境准备与一键部署

理论了解完毕,我们开始动手。为了让整个过程尽可能简单,我们将使用一个预配置好的Docker镜像来部署,这能避免复杂的依赖环境问题。

2.1 基础环境要求

在开始之前,请确保你的系统满足以下最低要求:

  • 操作系统:Linux(如Ubuntu 20.04/22.04)或 macOS。Windows用户建议使用WSL2。
  • Docker:确保已安装Docker Engine和Docker Compose。你可以通过运行 docker --versiondocker compose version 来检查。
  • 硬件:这是关键。
    • GPU:推荐使用NVIDIA GPU以获得最佳体验。需要安装好对应的NVIDIA驱动和 nvidia-docker 运行时。
    • 显存至少需要24GB的GPU显存。因为教程使用的镜像是全精度(fp16)模型,没有经过量化。如果你的显存不足,后续可以考虑使用量化版本的模型或寻找其他部署方式。
    • 内存:建议系统内存不小于32GB。
    • 磁盘空间:预留至少40GB的可用空间用于拉取镜像和模型文件。

2.2 一键启动服务

假设你的环境已经就绪,部署过程可以非常简洁。我们通过Docker Compose来管理服务。

  1. 创建项目目录并编写配置文件: 在你的工作目录下,创建一个名为 docker-compose.yml 的文件,并填入以下内容。这个配置会拉取预置的镜像,并启动模型服务和Web交互界面。

    version: '3.8'
    
    services:
      glm-4v-9b-service:
        image: registry.cn-hangzhou.aliyuncs.com/kakajiang/glm-4v-9b:latest
        container_name: glm-4v-9b
        runtime: nvidia # 使用NVIDIA容器运行时
        deploy:
          resources:
            reservations:
              devices:
                - driver: nvidia
                  count: all
                  capabilities: [gpu]
        ports:
          - "7860:7860" # 将容器的7860端口映射到主机的7860端口,用于Web UI
          - "8000:8000" # 将容器的8000端口映射到主机的8000端口,用于API服务
        volumes:
          - ./data:/app/data # 可选:挂载一个本地目录,用于持久化数据
        restart: unless-stopped
    
  2. 启动服务: 打开终端,进入存放 docker-compose.yml 文件的目录,运行以下命令:

    docker compose up -d
    

    这个命令会从镜像仓库拉取镜像(首次运行时间较长,取决于网络速度),然后在后台启动容器。

  3. 等待服务就绪: 启动后,需要耐心等待几分钟。系统需要完成两件事:

    • 在容器内部,使用vLLM引擎加载GLM-4v-9b模型。
    • 启动Open WebUI服务。 你可以通过以下命令查看容器日志,确认启动状态:
    docker compose logs -f glm-4v-9b
    

    当你看到日志中出现类似 “Uvicorn running on http://0.0.0.0:7860”“Model loaded successfully” 的信息时,说明服务已经启动成功。

2.3 访问Web交互界面

服务启动后,你有两种方式访问:

  1. 通过Web UI(推荐):打开你的浏览器,访问 http://你的服务器IP地址:7860。如果你是在本地机器上运行,直接访问 http://localhost:7860 即可。
  2. 通过Jupyter(可选):如果你更习惯在Notebook环境中操作,也可以访问 http://你的服务器IP地址:8888,然后将URL中的端口号 8888 手动改为 7860,同样可以跳转到Web UI。

登录信息: 为了演示,镜像中预置了一个账号。

  • 账号:kakajiang@kakajiang.com
  • 密码:kakajiang

请使用此账号登录,即可开始体验GLM-4v-9b的图文对话功能。

3. 图文对话上手实践

登录Web UI后,你会看到一个简洁的聊天界面。接下来,我们通过几个实际的例子,来感受一下GLM-4v-9b的能力。

3.1 基础功能:上传图片并提问

这是最核心的用法。界面通常有一个图片上传按钮或拖拽区域。

  1. 上传一张图片:你可以找一张风景照、一个产品界面截图、或者一张数据图表。比如,上传一张折线图。
  2. 输入你的问题:在输入框里,用自然语言描述你的需求。例如:
    • “描述一下这张图片里的内容。”
    • “这张折线图展示了什么趋势?最高点和最低点分别是多少?”
    • “图片里的这个按钮是做什么用的?”
  3. 查看回答:模型会分析图片,并结合你的问题生成回答。对于图表,它可能会总结数据趋势、识别关键数据点;对于截图,它可能会描述界面元素和功能。

试试看:找一张带有中文文字的复杂图片(比如一张会议白板照片),问问它:“白板上写了哪些关键议题?” 看看它识别中文手写或印刷文字的能力如何。

3.2 进阶技巧:多轮对话与细节追问

GLM-4v-9b支持上下文连贯的多轮对话,这是体现其智能的关键。

  1. 第一轮:上传一张智能手机的发布会海报,问:“这张海报在宣传什么产品?”
  2. 第二轮:基于它的回答(比如“宣传的是XX品牌新手机”),接着问:“海报上突出了这款手机的哪些新特性?”
  3. 第三轮:继续追问:“根据海报设计,你觉得这款手机的目标用户是谁?”

你会发现,模型在后续回答中,能记住前面提到的“手机”、“海报”等上下文,从而给出更精准、连贯的分析。你可以通过不断追问,引导它挖掘出图片中更深层的信息。

3.3 理解<image>标记注入

这是GLM-4v-9b的一个强大特性,也是我们后面接入LlamaIndex的基础。在与模型进行API交互时,你并不是简单地把图片二进制数据传过去,而是需要遵循一种特定的“对话格式”。

模型的输入期望一个由多个“消息”组成的列表,每个消息包含“角色”(如user)和“内容”。在“内容”字段里,你可以混合放置文本和图片标记。图片标记的格式通常是一个包含图片路径或Base64编码数据的字典,并被一个特殊的<image>标签所引用。

例如,一个合法的API请求数据可能看起来像这样(概念示意):

messages = [
    {
        "role": "user",
        "content": [
            {"type": "text", "text": "请分析这张图表:"},
            {"type": "image_url", "image_url": {"url": "file:///path/to/your/chart.png"}},
            {"type": "text", "text": "它说明了什么问题?"}
        ]
    }
]

在底层,这个结构会被转换成模型能理解的,包含<image>占位符的文本序列。Web UI帮我们封装了这一切,但当我们想编程调用,尤其是构建RAG系统时,就必须理解这种格式。

4. 接入LlamaIndex构建多模态RAG

现在我们来点更酷的。RAG(检索增强生成)能让大模型回答问题时,参考你提供的专属文档资料,避免“胡言乱语”。LlamaIndex是一个流行的框架,能帮你轻松构建RAG系统。GLM-4v-9b的多模态能力,使得我们可以构建一个能处理图文混合知识库的RAG。

4.1 核心思路

想象一下,你有一个产品手册文件夹,里面既有PDF文档,也有大量的截图和示意图。传统RAG只能处理文字,图片信息就浪费了。我们的目标是:

  1. 索引阶段:提取所有文档中的文字,同时,使用GLM-4v-9b为每一张图片生成一段详细的文字描述。
  2. 检索阶段:当用户提出一个问题时,系统同时从“文本库”和“图片描述库”中搜索相关片段。
  3. 生成阶段:将检索到的相关文本和图片描述(或者甚至图片本身,通过<image>标记)一起喂给GLM-4v-9b,让它综合这些信息生成最终答案。

这样,即使用户的问题是基于某张图片的内容,系统也能通过图片描述找到它,并让模型“看到”原图来回答。

4.2 简易实现步骤

下面是一个高度简化的代码示例,展示如何用LlamaIndex和GLM-4v-9b的API搭建一个多模态RAG的原型。假设你已经启动了上一节的服务,API端点位于 http://localhost:8000/v1

import os
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex, StorageContext
from llama_index.core.node_parser import SimpleNodeParser
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core.schema import ImageNode, TextNode
import chromadb
from openai import OpenAI

# 1. 初始化GLM-4v-9b的客户端(兼容OpenAI API格式)
client = OpenAI(
    api_key="no-key-required", # 我们的本地服务通常不需要key
    base_url="http://localhost:8000/v1" # 指向本地启动的vLLM API服务
)

# 2. 准备一个嵌入模型(用于文本向量化)
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-zh-v1.5")

# 3. 初始化向量数据库
chroma_client = chromadb.PersistentClient(path="./chroma_db")
chroma_collection = chroma_client.get_or_create_collection("multimodal_rag")
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)

# 4. 读取文档和图片
documents = []
image_files = []

data_dir = "./your_data_folder"
for file_name in os.listdir(data_dir):
    file_path = os.path.join(data_dir, file_name)
    if file_name.lower().endswith(('.png', '.jpg', '.jpeg')):
        image_files.append(file_path)
    elif file_name.lower().endswith('.txt'):
        with open(file_path, 'r', encoding='utf-8') as f:
            text = f.read()
            documents.append(TextNode(text=text, metadata={"source": file_name}))
    # 可以扩展支持PDF、Word等格式

# 5. 为每张图片生成描述,并创建ImageNode
for img_path in image_files:
    # 这里需要将图片转换为Base64或可访问的URL,然后调用GLM-4v-9b生成描述
    # 以下为概念性代码
    # with open(img_path, "rb") as img_file:
    #     base64_image = base64.b64encode(img_file.read()).decode('utf-8')
    #
    # response = client.chat.completions.create(
    #     model="glm-4v-9b", # 模型名
    #     messages=[
    #         {
    #             "role": "user",
    #             "content": [
    #                 {"type": "text", "text": "请详细描述这张图片的内容。"},
    #                 {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}},
    #             ],
    #         }
    #     ],
    #     max_tokens=300,
    # )
    # image_description = response.choices[0].message.content

    # 为简化示例,我们假设已经得到了描述
    image_description = f"这是一张关于XXX的图片,内容包含YYY和ZZZ。"
    
    # 创建ImageNode,其文本内容为图片描述,并存储图片路径在元数据中
    img_node = ImageNode(
        text=image_description,
        image_path=img_path,
        metadata={"source": os.path.basename(img_path), "type": "image"}
    )
    documents.append(img_node)

# 6. 构建索引(将文本和图片描述一起向量化存储)
index = VectorStoreIndex.from_documents(
    documents,
    storage_context=storage_context,
    embed_model=embed_model,
    show_progress=True
)

# 7. 创建查询引擎
query_engine = index.as_query_engine(
    similarity_top_k=3, # 检索最相关的3个片段
    response_mode="compact" # 响应模式
)

# 8. 进行查询
response = query_engine.query("我们产品的仪表盘界面是什么样的?")
print(response)

这段代码做了什么?

  1. 连接我们本地部署的GLM-4v-9b API。
  2. 读取一个文件夹,区分开文本文件和图片文件。
  3. 对于每张图片,调用GLM-4v-9b为其生成一段文字描述。
  4. 将所有原始文本和“图片描述文本”都转换成向量,存储到Chroma向量数据库中。
  5. 当用户提问时,系统从数据库中检索出与问题最相关的几段文本(其中可能包含对某张图片的描述)。
  6. 将这些检索到的文本片段作为上下文,发送给GLM-4v-9b,让它生成最终答案。

更进一步:在更高级的实现中,你可以在最终生成答案时,不仅提供图片描述,还可以将检索到的原始图片路径,通过<image>标记的方式注入到给模型的提示中,让模型直接“看到”原图,获得更精确的信息。

5. 总结与后续探索

通过这篇教程,我们完成了从理论认知、环境部署、基础使用到进阶集成的完整旅程。你现在应该已经能够:

  • 独立部署:在满足硬件条件的机器上,通过Docker一键启动GLM-4v-9b服务。
  • 熟练使用:通过Web界面与模型进行有效的图文对话,利用多轮追问挖掘图片深层信息。
  • 理解原理:明白了模型交互背后的<image>标记注入机制。
  • 初步集成:了解了如何将GLM-4v-9b与LlamaIndex框架结合,构建一个能够处理图文混合知识库的多模态RAG系统原型。

GLM-4v-9b凭借其优秀的性能、亲民的硬件要求和开放的开源策略,为开发者探索多模态AI应用打开了一扇非常实用的大门。无论是用于自动化内容审核、智能客服看图应答、教育领域的图解问答,还是企业内部知识库的智能化升级,它都是一个值得投入时间研究的强大工具。

下一步,你可以尝试

  • 性能优化:尝试使用INT4或INT8量化版本的模型,在显存更小的显卡上运行。
  • 深入集成:完善上面的RAG示例,实现真正的图片原图检索与注入,而不仅仅是使用图片描述。
  • 探索更多场景:将它接入你的工作流,比如自动分析UI设计稿、解读数据报告截图、创建可交互的产品说明书等。

希望这篇教程能成为你探索多模态AI世界的一块坚实跳板。动手去试,你会发现更多可能性。


获取更多AI镜像

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

Logo

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

更多推荐