当前位置: 首页 > news >正文

wow-rag:task2-正式上路搞定模型

我们计划采用Llama-index来做RAG。Langchain也是个不错的选择。我们之后会加入Langchain的版本,不过目前只做了Llama-index的教程。干活之前我们先准备好必备模型。一个llm模型,和一个embedding模型。

想要借助Llama-index构建llm和embedding模型,我们大体上有四种思路。

  • 第一个思路:使用Llama-index为各个厂家单独构建的服务,比如Llama-index为智谱和零一万物构建了专门的包,我们可以直接安装使用。
  • 第二个思路:如果Llama-index没有为某个厂家构建的服务,我们可以借助Llama-index为openai构建的库。只要我们国内的模型是openai兼容型的,我们就可以稍微修改一下源码直接使用。
  • 第三个思路:我们可以利用Llama-index提供的自定义类来自定义模型。
  • 第四个思路:我们可以在本地安装Ollama,在本地安装好模型,然后在Llama-index中使用Ollama的服务。

第一个思路,使用Llama-index为智谱构建的专门的包,直接安装最新版本即可。

%pip install llama-index-core
%pip install llama-index-embeddings-zhipuai
%pip install llama-index-llms-zhipuai
%pip install llama-index-readers-file
%pip install llama-index-vector-stores-faiss
%pip install llamaindex-py-client

跟第一节课的开头一样,咱们现在先把四样前菜准备一下吧:

import os
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()
# 从环境变量中读取api_key
api_key = os.getenv('ZHIPU_API_KEY')
base_url = "https://open.bigmodel.cn/api/paas/v4/"
chat_model = "glm-4-flash"
emb_model = "embedding-2"

配置对话模型

from llama_index.llms.zhipuai import ZhipuAI
llm = ZhipuAI(
    api_key = api_key,
    model = chat_model,
)

测试对话模型

# 测试对话模型
response = llm.complete("你是谁?")
print(response)

配置嵌入模型

# 配置嵌入模型
from llama_index.embeddings.zhipuai import ZhipuAIEmbedding
embedding = ZhipuAIEmbedding(
    api_key = api_key,
    model = emb_model,
)

测试嵌入模型

# 测试嵌入模型
emb = embedding.get_text_embedding("你好呀呀")
len(emb), type(emb)

输出 (1024, list)

说明配置成功。
在这里插入图片描述

第二个思路,借助openai的库,里面接入国内的模型

直接安装最新版本

如果是在jupyter notebook里运行,需要先用魔法命令安装这些库。

%pip install llama-index-core
%pip install llama-index-embeddings-openai
%pip install llama-index-llms-openai
%pip install llama-index-readers-file
%pip install llama-index-vector-stores-faiss
%pip install llamaindex-py-client

我们想要借助llama_index的OpenAI接口使用其他厂家的模型,通过翻阅源码,发现llama index 把OpenAI和OpenAIEmbedding的模型名称写死在代码里了,它会检查每个模型的输入上下文大小,如果模型没有在他的列表中,就会报错。所以我们可以重写一下llama_index的OpenAI类,通过新建一个NewOpenAI类,并继承OpenAI类,我们直接把输入上下文大小写死,不让它检查了,它就不报错了。

重写OpenAI类:

from llama_index.llms.openai import OpenAI
from llama_index.core.base.llms.types import LLMMetadata,MessageRole
class NewOpenAI(OpenAI):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    @property
    def metadata(self) -> LLMMetadata:
        # 创建一个新的LLMMetadata实例,只修改context_window
        return LLMMetadata(
            context_window=8192,
            num_output=self.max_tokens or -1,
            is_chat_model=True,
            is_function_calling_model=True,
            model_name=self.model,
            system_role=MessageRole.USER,
        )

重写完后,我们用NewOpenAI这个类来配置llm。

llm = NewOpenAI(
    temperature=0.95,
    api_key = api_key,
    model = chat_model,
    api_base = base_url # 注意这里单词不一样
)

测试对话模型

response = llm.complete("你是谁?")
print(response)

在这里插入图片描述

第三个思路:自定义模型接口

自定义可以利用openai-like的包,来封装任何openai类似的大模型
这个思路的缺点很明显,只有对话模型,没有嵌入模型。

虽然不推荐这个方式,但是如果实在想要尝试,先安装这个库:

%pip install llama-index-llms-openai-like

对话模型可以直接使用

from llama_index.llms.openai_like import OpenAILike

llm = OpenAILike(
    model = chat_model,
    api_base = base_url,
    api_key = api_key,
    is_chat_model=True
)

自定义对话模型

# 导入必要的库和模块
from openai import OpenAI
from pydantic import Field  # 导入Field,用于Pydantic模型中定义字段的元数据
from typing import Optional, List, Mapping, Any, Generator
import os

from llama_index.core import SimpleDirectoryReader, SummaryIndex
from llama_index.core.callbacks import CallbackManager
from llama_index.core.llms import (
    CustomLLM,
    CompletionResponse,
    CompletionResponseGen,
    LLMMetadata,
)
from llama_index.core.llms.callbacks import llm_completion_callback
from llama_index.core import Settings

# 定义OurLLM类,继承自CustomLLM基类
class OurLLM(CustomLLM):
    api_key: str = Field(default=api_key)
    base_url: str = Field(default=base_url)
    model_name: str = Field(default=chat_model)
    client: OpenAI = Field(default=None, exclude=True)  # 显式声明 client 字段

    def __init__(self, api_key: str, base_url: str, model_name: str = chat_model, **data: Any):
        super().__init__(**data)
        self.api_key = api_key
        self.base_url = base_url
        self.model_name = model_name
        self.client = OpenAI(api_key=self.api_key, base_url=self.base_url)  # 使用传入的api_key和base_url初始化 client 实例

    @property
    def metadata(self) -> LLMMetadata:
        """Get LLM metadata."""
        return LLMMetadata(
            model_name=self.model_name,
        )

    @llm_completion_callback()
    def complete(self, prompt: str, **kwargs: Any) -> CompletionResponse:
        response = self.client.chat.completions.create(model=self.model_name, messages=[{"role": "user", "content": prompt}])
        if hasattr(response, 'choices') and len(response.choices) > 0:
            response_text = response.choices[0].message.content
            return CompletionResponse(text=response_text)
        else:
            raise Exception(f"Unexpected response format: {response}")

    @llm_completion_callback()
    def stream_complete(
        self, prompt: str, **kwargs: Any
    ) -> Generator[CompletionResponse, None, None]:
        response = self.client.chat.completions.create(
            model=self.model_name,
            messages=[{"role": "user", "content": prompt}],
            stream=True
        )

        try:
            for chunk in response:
                chunk_message = chunk.choices[0].delta
                if not chunk_message.content:
                    continue
                content = chunk_message.content
                yield CompletionResponse(text=content, delta=content)

        except Exception as e:
            raise Exception(f"Unexpected response format: {e}")

# 测试对话模型
llm = OurLLM(api_key=api_key, base_url=base_url, model_name=chat_model)
response = llm.complete("你是谁?")
print(response)

自定义嵌入模型

from openai import OpenAI
from typing import Any, List
from llama_index.core.embeddings import BaseEmbedding
from pydantic import Field


class OurEmbeddings(BaseEmbedding):
    api_key: str = Field(default=api_key)
    base_url: str = Field(default=base_url)
    model_name: str = Field(default=emb_model)
    client: OpenAI = Field(default=None, exclude=True)  # 显式声明 client 字段

    def __init__(
        self,
        api_key: str = api_key, 
        base_url: str = base_url,
        model_name: str = emb_model,
        **kwargs: Any,
    ) -> None:
        super().__init__(**kwargs)
        self.api_key = api_key
        self.base_url = base_url
        self.model_name = model_name
        self.client = OpenAI(api_key=self.api_key, base_url=self.base_url) 

    def invoke_embedding(self, query: str) -> List[float]:
        response = self.client.embeddings.create(model=self.model_name, input=[query])

        # 检查响应是否成功
        if response.data and len(response.data) > 0:
            return response.data[0].embedding
        else:
            raise ValueError("Failed to get embedding from ZhipuAI API")

    def _get_query_embedding(self, query: str) -> List[float]:
        return self.invoke_embedding(query)

    def _get_text_embedding(self, text: str) -> List[float]:
        return self.invoke_embedding(text)

    def _get_text_embeddings(self, texts: List[str]) -> List[List[float]]:
        return [self._get_text_embedding(text) for text in texts]

    async def _aget_query_embedding(self, query: str) -> List[float]:
        return self._get_query_embedding(query)

    async def _aget_text_embedding(self, text: str) -> List[float]:
        return self._get_text_embedding(text)

    async def _aget_text_embeddings(self, texts: List[str]) -> List[List[float]]:
        return self._get_text_embeddings(texts)


在这里插入图片描述

来测试一下自定义的嵌入模型

embedding = OurEmbeddings(api_key=api_key, base_url=base_url, model_name=emb_model)
emb = embedding.get_text_embedding("你好呀呀")
len(emb), type(emb)

(1024, list)

第四个思路:我们可以在本地安装Ollama

Ollama里的qwen2系列非常棒,有很多尺寸规模的模型,最小的模型只有 0.5b,然后还有1.5b、7b、32b等等,可以适应各种设备。
访问 https://ollama.com。 下载Windows版本。直接安装。 安装完成后,打开命令行窗口,输入 ollama,如果出现 Usage: Available Commands: 之类的信息,说明安装成功。
我们用qwen2:7b这个模型就行,整个还不到4G。 运行 ollama run qwen2:7b
如果出现了success,就说明安装成功。 然后会出现一个>>>符号,这就是对话窗口。可以直接输入问题。
想要退出交互页面,直接输入 /bye 就行。斜杠是需要的。否则不是退出交互页面,而是对大模型说话,它会继续跟你聊。
在浏览器中输入 127.0.0.1:11434,如果出现 Ollama is running
说明端口运行正常。

安装完ollama后,我们还需要进行配置一下,主要是两个方面。这个配置只有在Windows电脑上试过。Linux和Mac抱歉还没有试过,需要的朋友可能要自己探索一下了。
第一:这时候模型是放在内存中的。我们希望把模型放在硬盘中。所以,我们可以在硬盘中建一个文件夹,比如: D:\programs\ollama\models
然后新建系统环境变量。 变量名: OLLAMA_MODELS
变量值: D:\programs\ollama\models
第二:这时候的大模型只能通过127.0.0.1:11434来访问。我们希望在局域网中的任何电脑都可以访问。这也是通过新建环境变量来解决。
变量名: OLLAMA_HOST 变量值: 0.0.0.0:11434
这样就完成了配置。是不是非常简单方便?

如果是在jupyter notebook里运行,需要先用魔法命令安装这些库。

%pip install llama-index-core
%pip install llama-index-embeddings-ollama
%pip install llama-index-llms-ollama
%pip install llama-index-readers-file
%pip install llama-index-vector-stores-faiss
%pip install llamaindex-py-client
# 我们先用requets库来测试一下大模型
import json
import requests
# 192.168.0.123就是部署了大模型的电脑的IP,
# 请根据实际情况进行替换
BASE_URL = "http://192.168.0.123:11434/api/chat"

直接输出看看:

payload = {
  "model": "qwen2:7b",
  "messages": [
    {
      "role": "user",
      "content": "请写一篇1000字左右的文章,论述法学专业的就业前景。"
    }
  ]
}
response = requests.post(BASE_URL, json=payload)
print(response.text)

然后改成流式输出:

payload = {
  "model": "qwen2:7b",
  "messages": [
    {
      "role": "user",
      "content": "请写一篇1000字左右的文章,论述法学专业的就业前景。"
    }
  ],
  "stream": True
}
response = requests.post(BASE_URL, json=payload, stream=True)  # 在这里设置stream=True告诉requests不要立即下载响应内容  
# 检查响应状态码  
if response.status_code == 200:  
    # 使用iter_content()迭代响应体  
    for chunk in response.iter_content(chunk_size=1024):  # 你可以设置chunk_size为你想要的大小  
        if chunk:  
            # 在这里处理chunk(例如,打印、写入文件等)  
            rtn = json.loads(chunk.decode('utf-8')) # 假设响应是文本,并且使用UTF-8编码  
            print(rtn["message"]["content"], end="")
else:  
    print(f"Error: {response.status_code}")  

# 不要忘记关闭响应  
response.close()

总结

使用 Llama-index 提供的专用服务包:

Llama-index 已经为一些模型提供商(如智谱和零一万物)构建了专门的集成包。
你可以直接安装这些包来使用对应的 LLM 和 embedding 模型,这是最直接和简便的方法。

利用 OpenAI 兼容型模型:

如果你的国内模型是 OpenAI 兼容型的,你可以利用 Llama-index 为 OpenAI 构建的库。
可能需要对源码进行少量修改以适应你的模型,但这种方法可以利用现有的 Llama-index 基础设施。

自定义模型集成:

Llama-index 提供了自定义类,允许你集成自己的 LLM 和 embedding 模型。
这种方法提供了最大的灵活性,可以根据你的具体需求定制模型集成。

本地安装 Ollama 并使用其服务:

在本地安装 Ollama,并配置好所需的 LLM 和 embedding 模型。
然后在 Llama-index 中使用 Ollama 提供的服务来进行 RAG 任务的构建。
这种方法需要在本地环境中进行较多的设置和配置。

每种思路都有其优缺点,选择哪种方法取决于你的具体需求、资源和技术能力。如果你希望快速上手并且模型提供商已经有现成的 Llama-index 包,第一种方法可能是最佳选择。如果你需要更大的灵活性或者使用的是兼容 OpenAI 的模型,第二或第三种方法可能更适合。如果你希望在本地环境中完全控制模型的部署和使用,第四种方法则提供了这种可能性。

相关文章:

  • 红帆 iOffice M2 移动端密码爆破的渗透测试思路,绕过客户端实现Burpsuite批量跑,分享渗透思路,共建网络安全
  • 二维数组基础
  • BLEU评估指标
  • 静态程序分析
  • 网络安全和文档的关系
  • 【高项】信息系统项目管理师(五)项目范围管理【3分】
  • CSS 知识点总结1
  • 在ArcGIS中对图斑进行自上而下从左往右编号
  • 制造业数字化转型,汽车装备制造企业数字化转型案例,智能制造数字化传统制造业数字化制造业数字化转型案例
  • 【运维】服务器系统从centos7重装为ubuntu22.04
  • 医院本地化DeepSeek R1对接混合数据库技术实战方案研讨
  • 使用Python在Word中生成多种不同类型的图表
  • 2020年SCI1区TOP:自适应粒子群算法MPSO,深度解析+性能实测
  • AI智能代码疫苗技术,赋能数字化应用内生安全自免疫
  • QT:非模态使用WA_DeleteOnClose避免内存泄漏
  • ESP32C3 ADC 检测电压
  • 【 Fail2ban 使用教程】
  • 力扣——两数相加
  • 每日一题--数据库
  • 建筑兔零基础自学记录45|获取高德/百度POI-1
  • 建设一个电商网站的步骤/今日头条武汉最新消息
  • 经营网站建设/产品网络营销分析
  • 昆明hph网站建设/新闻营销
  • 网站内容设计基本原则/重庆seo推广服务
  • 企业宣传网站怎么做/注册城乡规划师好考吗
  • 网站建设项目竞争性招标文件/张文宏说上海可能是疫情爆发