在本地运行 Mixtral 8x7 与 LlamaIndex [译]

作者:

LlamaIndex

你可能已经听说了来自欧洲 AI 领头羊 Mistral AI 的最新大作——Mixtral 8x7b。这是一个包含八个各自拥有 70 亿参数的“专家混合”模型,名字中的“8x7”正是由此而来。它最初通过一条引人注目的 推文 首次亮相,紧接着几天后他们发布了一篇 博客文章,展示了该模型在多项基准测试中与 GPT-3.5 一较高下,甚至在某些方面超越了体量更大的 Llama2 70b。

在 LlamaIndex,我们是开源软件的忠实支持者,因此像 Mixtral 这样开放的模型和具有灵活授权的项目正合我们心意。我们收到了不少关于如何将 Mixtral 与 LlamaIndex 结合使用的咨询,因此本文将指导你如何在本地完全独立地运行这一模型。

步骤 1:安装 Ollama

过去,在本地安装并运行模型是一件相当复杂的事,但随着 Ollama 的推出,这一切变得简单多了!Ollama 支持 MacOS 和 Linux 系统(Windows 版本也即将推出,不过目前你可以通过 Windows Subsystem For Linux 在 Windows 上使用)。Ollama 是开源软件,并提供了 免费下载

下载完成后,你可以通过一个简单的命令来安装 Mixtral:

ollama run mixtral

首次运行此命令时,需要下载模型,这可能会花费一些时间,你可以利用这段时间休息一下。需要注意的是,运行它需要高达 48GB 的 RAM!如果你的电脑配置达不到这个要求,你可以考虑使用性能稍逊但依然强大的 Mistral 7b,其安装和运行方式与 Mixtral 相同:

ollama run mistral

本教程假设你使用 Mixtral,不过 Mistral 也同样适用。

一旦模型启动,Ollama 会自动允许你与其进行交互。这本身很有趣,但我们的目标不仅仅是与模型聊天,而是要让它能够处理你的数据。这就是 LlamaIndex 发挥作用的地方。接下来的步骤将带你逐行了解相关代码,不过如果你不想手动复制粘贴,可以直接访问这个 开源仓库,里面有完整的代码,你可以克隆后跟着做。

步骤 2:安装依赖项

首先,你需要安装 LlamaIndex。除此之外,我们还会介绍一些即将派上用场的其他依赖项:

pip install llama-index qdrant_client torch transformers

步骤 3:基本功能测试

如果你已经成功运行 Ollama 并正确安装了 LlamaIndex,下面这个简单的脚本可以通过执行一个基本功能测试来确认一切是否正常。这个测试是一个独立的脚本:

## Just runs .complete to make sure the LLM is listening
from llama_index.llms import Ollama
llm = Ollama(model="mixtral")
response = llm.complete("Who is Laurie Voss?")
print(response)

第 4 步:加载并索引数据

现在你可以开始加载一些实际的数据了。你可以使用任意数据,在此例中,我用的是我自己的一些推文集合,你也可以下载使用或者用自己的数据。我们将使用高效的开源向量数据库 Qdrant(Qdrant)来存储数据,这就是我们之前让你安装它的原因。请创建一个新的 python 文件,并导入所有必要的依赖项:

from pathlib import Path
import qdrant_client
from llama_index import (
VectorStoreIndex,
ServiceContext,
download_loader,
)
from llama_index.llms import Ollama
from llama_index.storage.storage_context import StorageContext
from llama_index.vector_stores.qdrant import QdrantVectorStore

接下来,利用 LlamaHub提供的一个实用的 JSONReader 从 JSON 文件中读取推文。这会生成一系列准备嵌入和索引的文档:

JSONReader = download_loader("JSONReader")
loader = JSONReader()
documents = loader.load_data(Path('./data/tinytweets.json'))

为了让 Qdrant 进入工作状态,我们需要初始化它,并将其加入到我们稍后要使用的存储上下文中:

client = qdrant_client.QdrantClient(
path="./qdrant_data"
)
vector_store = QdrantVectorStore(client=client, collection_name="tweets")
storage_context = StorageContext.from_defaults(vector_store=vector_store)

现在,我们来设置服务上下文。我们会使用 Mixtral 作为大语言模型(LLM)进行测试,以确保在我们完成索引后一切正常;实际的索引过程并不需要用到 Mixtral。通过设置 embed_model="local",我们让 LlamaIndex 在本地处理数据嵌入,这就是为何你需要安装 torchtransformers

llm = Ollama(model="mixtral")
service_context = ServiceContext.from_defaults(llm=llm,embed_model="local")

最后,把这一切结合起来:利用你已经准备好的服务和存储上下文,从加载的文档中构建索引,并进行一次查询:

index = VectorStoreIndex.from_documents(documents,service_context=service_context,storage_context=storage_context)
query_engine = index.as_query_engine()
response = query_engine.query("What does the author think about Star Trek? Give details.")
print(response)

Ollama 在处理查询时需要启动 Mixtral,这可能需要一些时间,请耐心等待。你最终应该会得到类似这样的输出(但内容会更丰富):

Based on the provided context information, the author has a mixed opinion about Star Trek.

验证索引的有效性

现在,为了证明这不只是表面功夫,我们将使用我们预先建立的索引。创建一个新的 Python 文件并重新加载必要的依赖项:

import qdrant_client
from llama_index import (
VectorStoreIndex,
ServiceContext,
)
from llama_index.llms import Ollama
from llama_index.vector_stores.qdrant import QdrantVectorStore

这一次我们无需再次加载数据,因为这已经完成了!我们需要的是 Qdrant 客户端和 Mixtral:

client = qdrant_client.QdrantClient(
path="./qdrant_data"
)
vector_store = QdrantVectorStore(client=client, collection_name="tweets")
llm = Ollama(model="mixtral")
service_context = ServiceContext.from_defaults(llm=llm,embed_model="local")

这次我们不是从文档中创建索引,而是直接从向量存储中使用 from_vector_store 命令加载它。我们还向查询引擎传递了 similarity_top_k=20 参数;这意味着它会一次性获取 20 条推文(默认是 2 条),从而提供更多的上下文,以便更准确地回答问题。

index = VectorStoreIndex.from_vector_store(vector_store=vector_store,service_context=service_context)
query_engine = index.as_query_engine(similarity_top_k=20)
response = query_engine.query("Does the author like SQL? Give details.")
print(response)

构建小型网络服务

仅仅拥有一个脚本形式运行的索引是不够的!我们将把它转换成一个 API。这需要引入两个新的依赖项:

pip install flask flask-cors

按照之前的方法在新文件中加载依赖项:

from flask import Flask, request, jsonify
from flask_cors import CORS, cross_origin
import qdrant_client
from llama_index.llms import Ollama
from llama_index import (
VectorStoreIndex,
ServiceContext,
)
from llama_index.vector_stores.qdrant import QdrantVectorStore

然后加载向量存储、大语言模型(LLM)和索引:

# re-initialize the vector store
client = qdrant_client.QdrantClient(
path="./qdrant_data"
)
vector_store = QdrantVectorStore(client=client, collection_name="tweets")
# get the LLM again
llm = Ollama(model="mixtral")
service_context = ServiceContext.from_defaults(llm=llm,embed_model="local")
# load the index from the vector store
index = VectorStoreIndex.from_vector_store(vector_store=vector_store,service_context=service_context)

接着,设置一个基础的 Flask 服务器:

app = Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'
# This is just so you can easily tell the app is running
@app.route('/')
def hello_world():
return 'Hello, World!'

添加一个路由,它能接收查询(以表单数据形式)、通过大语言模型处理查询并返回结果:

@app.route('/process_form', methods=['POST'])
@cross_origin()
def process_form():
query = request.form.get('query')
if query is not None:
query_engine = index.as_query_engine(similarity_top_k=20)
response = query_engine.query(query)
return jsonify({"response": str(response)})
else:
return jsonify({"error": "query field is missing"}), 400
if __name__ == '__main__':
app.run()

注意最后两行代码,它们非常关键!由于 flask run 命令与 LlamaIndex 加载依赖的方式不兼容,因此你需要像这样直接运行你的 API(假设你的文件命名为 app.py

python app.py

当你的 API 启动后,你可以使用 cURL 来发送请求并进行验证:

curl --location '<http://127.0.0.1:5000/process_form>' \\--form 'query="What does the author think about Star Trek?"'

完成!

我们在本教程中涉及了以下几个方面:

  • 如何在本地运行 Mixtral
  • 使用 LlamaIndex 查询 Mixtral 8x7b
  • 利用 Qdrant 向量存储来构建和查询数据索引
  • 将索引封装成一个非常简单的网络 API
  • 所有这些都是开源、免费,并且可以在本地运行的!

希望这是一个简单有趣的引导,帮助你学会如何使用 LlamaIndex 在本地运行模型!