2023年7月11日,百川智能正式发布参数量130亿的通用大语言模型Baichuan-13B-Base、对话模型Baichuan-13B-Chat及其INT4/INT8两个量化版本。

本文将介绍大模型BaiChuan-13B-Chat的使用体验,其HuggingFace网址为:https://huggingface.co/baichuan-inc/Baichuan-13B-Chat

BaiChuan-13B-Chat模型采用FastChat工具部署,部署方式与Baichuan-7B模型相同,关于部署的详细步骤,可参考文章:NLP(五十九)使用FastChat部署百川大模型


使用初体验

GPT3.5或者GPT4模型在中文问答上偶尔会出现“幻觉”问题,比如一些常识性的中文问题,在这方面,Baichuan-13B-Chat模型的表现较好。

我们考虑以下三个问题:

  • 鲁迅和周树人是同一个人吗,简要回答?
  • 中国第三大岛是哪个?
  • 拉普拉斯获得过诺贝尔奖吗?

这是GPT3.5的回答:

NLP(六十)Baichuan-13B-Chat模型使用体验_NLP

这是GPT4的回复:

NLP(六十)Baichuan-13B-Chat模型使用体验_NLP_02

这是Baichuan-13B-Chat模型的回复:

NLP(六十)Baichuan-13B-Chat模型使用体验_NLP_03

向量嵌入(Embedding)

当我们完成Baichuan-13B-Chat模型的部署后,我们可以使用类似OpenAI的调用方式来调用该模型,以下是其在向量嵌入方面的表现。

我们选择五个初始文本:

  • 唯心主义的对立面是什么
  • 你好
  • 上海的人口是多少?
  • 北京的旅游景点有哪些?
  • 中国的第一高楼

首先使用模型对以上文本进行向量嵌入(Embedding),向量维度为512维,范数为1(即已经进行规范化)。再使用新的文本进行向量嵌入,通过向量的余弦相似度获得五个文本中的最相似文本。实现Python如下:

# -*- coding: utf-8 -*-
import requests
import json
import numpy as np


def get_text_embedding(text):
	# Baichuan-13B-Chat Embedding
    url = "http://localhost:8000/v1/embeddings"
    headers = {'Content-Type': 'application/json'}
    payload = json.dumps({
        "model": "Baichuan-13B-Chat",
        "input": text
    })
    response = requests.request("POST", url, headers=headers, data=payload)
    return response.json()["data"][0]['embedding']


contents = ["唯心主义的对立面是什么",
            "你好",
            "上海的人口是多少?",
            "北京的旅游景点有哪些?",
            "中国的第一高楼"]

embeddings = [get_text_embedding(content) for content in contents]

new_text = '苏州的旅游景点有哪些?'
new_embedding = get_text_embedding(new_text)

cosine_sim_list = []
for embedding in embeddings:
    cosine_sim_list.append(np.dot(np.array(new_embedding), np.array(embedding)))

print(f'输入:{new_text}')
print(f'最相似文本:{contents[cosine_sim_list.index(max(cosine_sim_list))]}')

测试结果如下:

输入:苏州的旅游景点有哪些? 最相似文本:北京的旅游景点有哪些?

输入:柏拉图的哲学思想是什么? 最相似文本:唯心主义的对立面是什么

输入:北京的人口 最相似文本:上海的人口是多少?

文档阅读

在向量嵌入的基础上,我们使用LangChain工具,将文档进行切分(split),之后转化为向量(Embedding),存入向量数据库(如Milvus),这样完成文档的储存。

对于用户的新问题,使用文本相似度进行向量数据库查询,找到最接近的K条文本,使用这K条文本和新问题,进行文档问答,类似于BERT时代的阅读理解(MRC)。

我们以中国载人登月工程百度百科中的文本为例,访问网址为:https://baike.baidu.com/item/%E4%B8%AD%E5%9B%BD%E8%BD%BD%E4%BA%BA%E7%99%BB%E6%9C%88%E5%B7%A5%E7%A8%8B/7147309 ,将其储存为txt文件。

NLP(六十)Baichuan-13B-Chat模型使用体验_NLP_04

以此为例进行文档问答,流程图参考如下:

NLP(六十)Baichuan-13B-Chat模型使用体验_NLP_05

实现Python代码如下:

# -*- coding: utf-8 -*-
import json
import requests
from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from pymilvus import (
    connections,
    utility,
    FieldSchema,
    CollectionSchema,
    DataType,
    Collection,
)

# 指定要使用的文档加载器
documents = TextLoader('dengyue.txt', encoding='utf-8').load()
# 接下来,我们将文档拆分成块。
text_splitter = RecursiveCharacterTextSplitter(chunk_size=250, chunk_overlap=0)
texts = text_splitter.split_documents(documents)


# 获取文本的向量嵌入,使用Baichuan-13B-Chat模型
def get_text_embedding(req_text):
    url = "http://localhost:8000/v1/embeddings"
    headers = {'Content-Type': 'application/json'}
    payload = json.dumps({"model": "Baichuan-13B-Chat", "input": req_text})
    new_req = requests.request("POST", url, headers=headers, data=payload)
    return new_req.json()['data'][0]['embedding']

# 使用Baichuan-13B-Chat模型获取文档问答的答案
def get_doc_qa(qa_template):
    url = "http://localhost:8000/v1/chat/completions"
    payload = json.dumps({
        "model": "Baichuan-13B-Chat",
        "messages": [
            {
                "role": "user",
                "content": qa_chain_prompt
            }
        ]
    })
    headers = {'Content-Type': 'application/json'}
    response = requests.request("POST", url, headers=headers, data=payload)
    return response.json()['choices'][0]['message']['content']


# 连接Milvus
connections.connect("default", host="localhost", port="19530")

# 创建一个collection
fields = [
    FieldSchema(name="pk", dtype=DataType.INT64, is_primary=True, auto_id=False),
    FieldSchema(name="source", dtype=DataType.VARCHAR, max_length=100),
    FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=1000),
    FieldSchema(name="embeddings", dtype=DataType.FLOAT_VECTOR, dim=5120)
]
schema = CollectionSchema(fields, "vector db for docs qa")
hello_milvus = Collection("docs_qa", schema)

# 数据插入
_ids = []
sources = []
contents = []
embeddings = []
for i, text in enumerate(texts):
    source = text.metadata['source']
    print(i+1, source)
    content = text.page_content
    embedding = get_text_embedding(content)
    _ids.append(i+1)
    sources.append(source)
    contents.append(content)
    embeddings.append(embedding)

insert_result = hello_milvus.insert([_ids, sources, contents, embeddings])
# After final entity is inserted, it is best to call flush to have no growing segments left in memory
hello_milvus.flush()

# 在entities字段创建索引
index = {
    "index_type": "IVF_FLAT",
    "metric_type": "IP",
    "params": {"nlist": 128},
}
hello_milvus.create_index("embeddings", index)

# 将collection加载至内存
hello_milvus.load()

# 输入问题,进行文档问答
while True:
    query = input('输入问题:')
    vectors_to_search = [get_text_embedding(query)]
    # 通过嵌入向量相似度获取相似文本,数量为3个
    search_params = {
        "metric_type": "IP",
        "params": {"nprobe": 10},
    }
    result = hello_milvus.search(vectors_to_search, "embeddings", search_params, limit=3, output_fields=["text"])
    context = ''.join([_.entity.get('text') for _ in result[0]])

    # 建立prompt
    qa_chain_prompt = f"""使用以下文本来回答最后的问题。
    如果你不知道答案,就说你不知道,不要试图编造答案,尽可能保持答案简洁。 
    文本: {context}
    问题: {query}
    答案:"""
    # print(qa_chain_prompt)
    print(f'问题:{query}')
    print(f'回答:{get_doc_qa(qa_chain_prompt)}')

测试结果如下:

问题:美国什么时候登上月球? 回答:美国在20世纪60年代和70年代通过“阿波罗”计划成功登上月球。

问题:中国预计在什么登上月球? 回答:中国预计在2025年实现航天员登月。目前,关于中国载人登月工程计划的时间,国内有三种说法:2020年、2025年和2030年。不过,这些时间表都是专家的观点和预测,国家尚未公布一个明确的时间表。

问题:嫦娥二号、嫦娥三号的总指挥是谁? 回答:嫦娥二号、嫦娥三号的总指挥是叶培建。

问题:神舟十六号载人飞行任务新闻发布会在哪里举行? 回答:神舟十六号载人飞行任务新闻发布会在酒泉卫星发射中心举行。

当然,上述的文档问答方案并不是很完善,仅仅使用向量嵌入有时无法召回相似文本,这样就会造成回答错误。

后续笔者将考虑ES + 向量加入的结合方式进行召回,同时支持更多类型的文本,不仅限于txt文件。

总结

本文主要介绍了Baichuan-13B-Chat模型使用体验,包括其与GPT系列模型在中文常识性问题上的测试,以及向量嵌入、文档问答等。

笔者使用下来的初步感受是,Baichuan-13B-Chat模型的问答效果还是不错的!

欢迎关注我的公众号NLP奇幻之旅,原创技术文章第一时间推送。

NLP(六十)Baichuan-13B-Chat模型使用体验_NLP_06