欢迎来到飞鸟慕鱼博客,开始您的技术之旅!
当前位置: 首页知识笔记正文

万字的笔画顺序,万字长文解析特斯拉自动驾驶体系

终极管理员 知识笔记 46阅读

h、Kibana、Beats在内的Elastic Stack生态组件还与Elastic官方合作提供免费X-Pack白金版高级特性商业插件集成了安全、SQL、机器学习、告警、监控等高级特性被广泛应用于实时日志分析处理、信息检索、以及数据的多维查询和统计分析等场景。

创建阿里云Elasticsearch实例。具体操作请参见创建阿里云Elasticsearch实例。后续步骤详见这里。

AnalyticDB

云原生数据仓库AnalyticDB PostgreSQL版是一种大规模并行处理MPP数据仓库服务可提供海量数据在线分析服务。它基于开源项目Greenplum构建由阿里云深度扩展兼容ANSI SQL 2003兼容PostgreSQL/Oracle数据库生态支持行存储和列存储模式。既提供高性能离线数据处理也支持高并发在线分析查询是各行业有竞争力的PB级实时数据仓库方案。

在AnalyticDB PostgreSQL版控制台上创建实例。具体操作请参见创建实例。后续步骤详见这里。

3.1.2 本地数据库

用户文档数较少非高频场景可以考虑使用FAISS等本地数据库方案轻量级且易于维护。

Faiss

Faiss (Facebook AI Similarity Search) 是FaceBook AI团队开源的针对大规模相似度检索的工具为稠密向量提供高效相似度搜索和聚类包含多种搜索任意大小向量集的算法对10亿量级的索引可以做到毫秒级检索的性能是目前较成熟的近似近邻搜索库。

使用Faiss构建本地向量库无需购买线上向量库产品也免去了线上开通向量库产品的复杂流程更轻量易用。

3.2 文本处理

在构建向量检索库前需要对知识库文档进行文本处理。包括数据清洗文本提取、超链替换等、语义切块chunk、QA提取等。

数据清洗

如果知识库文本较脏或不规范需要先做些数据清洗如将PDF提取为txt文本将文本中的超链接提取出等。处理代码需要根据具体文本形式定制。如源知识库如果是html格式需要首先按html标题进行切分保证内容完整性。并对部分文档类别如常见问题产品简介发布记录等进行筛选单独处理等。

语义切块chunk

对于非结构化文档文本将通过TextSplitter被切分为固定大小的chunks这些chunks将被作为不同的知识条目用于辅助LLM生成回答。

如果知识库文本较干净或已经过处理可以直接根据文档中标题语段进行切分也可使用LangChain提供的语义切块接口CharacterTextSplitter代码如下

from langchain.text_splitter import CharacterTextSplittertext_splitter  CharacterTextSplitter(chunk_size, chunk_overlap)def split_documents(docs):    return text_splitter.split_documents(docs)

完成切chunk后建议为每个chunk生成对应标题或短摘要方便后续存入向量库时作为查询主键。

QA提取

实际应用中发现使用QA替代纯文本语块在向量检索时效果显著更好。因此可基于现有非结构化文本自动生成一些QA对并将其embedding化后存入向量库中。

3.3 Embedding模型

这部分根据切分的chunk或提取出的QA调用开源的embedding模型以chunk标题或Q生成的embedding作为索引键chunk或A生成的embedding作为检索值。这里介绍几种常用的开源embedding模型。

3.3.1 text2vec

text2vec 实现了Word2Vec、RankBM25、BERT、Sentence-BERT、CoSENT等多种文本表征、文本相似度计算模型并在文本语义匹配相似度计算任务上比较了各模型的效果。

3.3.2 SGPT

SGPT (GPT Sentence Embeddings for Semantic Search) 是一种使用GPT架构生成embedding的方法模型架构如下使用 Cross-Encoder 和 Bi-Encoder 两种方式进行嵌入表示学习。

以非对称 Bi-Encoder 的 SGPT 为例其语义向量检索代码如下

import torchfrom transformers import AutoModel, AutoTokenizerfrom scipy.spatial.distance import cosine# Get our models - The package will take care of downloading the models automatically# For best performance: Muennighoff/SGPT-5.8B-weightedmean-msmarco-specb-bitfittokenizer  AutoTokenizer.from_pretrained(Muennighoff/SGPT-125M-weightedmean-msmarco-specb-bitfit)model  AutoModel.from_pretrained(Muennighoff/SGPT-125M-weightedmean-msmarco-specb-bitfit)# Deactivate Dropout (There is no dropout in the above models so it makes no difference here but other SGPT models may have dropout)model.eval()queries  [    Im searching for a planet not too far from Earth.,]docs  [    Neptune is the eighth and farthest-known Solar planet from the Sun. In the Solar System, it is the fourth-largest planet by diameter, the third-most-massive planet, and the densest giant planet. It is 17 times the mass of Earth, slightly more massive than its near-twin Uranus.,    TRAPPIST-1d, also designated as 2MASS J23062928-0502285 d, is a small exoplanet (about 30% the mass of the earth), which orbits on the inner edge of the habitable zone of the ultracool dwarf star TRAPPIST-1 approximately 40 light-years (12.1 parsecs, or nearly 3.7336×1014 km) away from Earth in the constellation of Aquarius.,    A harsh desert world orbiting twin suns in the galaxy’s Outer Rim, Tatooine is a lawless place ruled by Hutt gangsters. Many settlers scratch out a living on moisture farms, while spaceport cities such as Mos Eisley and Mos Espa serve as home base for smugglers, criminals, and other rogues.,]SPECB_QUE_BOS  tokenizer.encode([, add_special_tokensFalse)[0]SPECB_QUE_EOS  tokenizer.encode(], add_special_tokensFalse)[0]SPECB_DOC_BOS  tokenizer.encode({, add_special_tokensFalse)[0]SPECB_DOC_EOS  tokenizer.encode(}, add_special_tokensFalse)[0]def tokenize_with_specb(texts, is_query):    # Tokenize without padding    batch_tokens  tokenizer(texts, paddingFalse, truncationTrue)       # Add special brackets & pay attention to them    for seq, att in zip(batch_tokens[input_ids], batch_tokens[attention_mask]):        if is_query:            seq.insert(0, SPECB_QUE_BOS)            seq.append(SPECB_QUE_EOS)        else:            seq.insert(0, SPECB_DOC_BOS)            seq.append(SPECB_DOC_EOS)        att.insert(0, 1)        att.append(1)    # Add padding    batch_tokens  tokenizer.pad(batch_tokens, paddingTrue, return_tensorspt)    return batch_tokensdef get_weightedmean_embedding(batch_tokens, model):    # Get the embeddings    with torch.no_grad():        # Get hidden state of shape [bs, seq_len, hid_dim]        last_hidden_state  model(**batch_tokens, output_hidden_statesTrue, return_dictTrue).last_hidden_state    # Get weights of shape [bs, seq_len, hid_dim]    weights  (        torch.arange(start1, endlast_hidden_state.shape[1]  1)        .unsqueeze(0)        .unsqueeze(-1)        .expand(last_hidden_state.size())        .float().to(last_hidden_state.device)    )    # Get attn mask of shape [bs, seq_len, hid_dim]    input_mask_expanded  (        batch_tokens[attention_mask]        .unsqueeze(-1)        .expand(last_hidden_state.size())        .float()    )    # Perform weighted mean pooling across seq_len: bs, seq_len, hidden_dim -> bs, hidden_dim    sum_embeddings  torch.sum(last_hidden_state * input_mask_expanded * weights, dim1)    sum_mask  torch.sum(input_mask_expanded * weights, dim1)    embeddings  sum_embeddings / sum_mask    return embeddingsquery_embeddings  get_weightedmean_embedding(tokenize_with_specb(queries, is_queryTrue), model)doc_embeddings  get_weightedmean_embedding(tokenize_with_specb(docs, is_queryFalse), model)# Calculate cosine similarities# Cosine similarities are in [-1, 1]. Higher means more similarcosine_sim_0_1  1 - cosine(query_embeddings[0], doc_embeddings[0])cosine_sim_0_2  1 - cosine(query_embeddings[0], doc_embeddings[1])cosine_sim_0_3  1 - cosine(query_embeddings[0], doc_embeddings[2])print(Cosine similarity between \%s\ and \%s\ is: %.3f % (queries[0], docs[0][:20]  ..., cosine_sim_0_1))print(Cosine similarity between \%s\ and \%s\ is: %.3f % (queries[0], docs[1][:20]  ..., cosine_sim_0_2))print(Cosine similarity between \%s\ and \%s\ is: %.3f % (queries[0], docs[2][:20]  ..., cosine_sim_0_3))
3.3.3 BGE

BGE (BAAI General Embedding) 是智源开源的中英文语义向量模型在3亿条中英文关联文本对上训练。是目前线上表现最好的开源向量模型

最新开源的BGE v1.5版本缓解了相似度分布问题通过对训练数据进行过滤删除低质量数据提高训练时温度系数 temperature 至 0.02使得相似度数值更加平稳。

BGE v1.5包含large、base、small三种尺寸的模型调用速度差距不大相比LLM生成时间基本可忽略因此实际线上使用时可以直接使用 bge-large。使用代码如下

from transformers import AutoTokenizer, AutoModelimport torch# Sentences we want sentence embeddings forsentences  [样例数据-1, 样例数据-2]# Load model from HuggingFace Hubtokenizer  AutoTokenizer.from_pretrained(BAAI/bge-large-zh-v1.5)model  AutoModel.from_pretrained(BAAI/bge-large-zh-v1.5)model.eval()# Tokenize sentencesencoded_input  tokenizer(sentences, paddingTrue, truncationTrue, return_tensorspt)# for s2p(short query to long passage) retrieval task, add an instruction to query (not add instruction for passages)# encoded_input  tokenizer([instruction  q for q in queries], paddingTrue, truncationTrue, return_tensorspt)# Compute token embeddingswith torch.no_grad():    model_output  model(**encoded_input)    # Perform pooling. In this case, cls pooling.    sentence_embeddings  model_output[0][:, 0]# normalize embeddingssentence_embeddings  torch.nn.functional.normalize(sentence_embeddings, p2, dim1)print(Sentence embeddings:, sentence_embeddings)

四、LLM训练及推理 4.1 指令微调 4.1.1 LLM选择

在当前检索增强的链路中LLM大多只负责检索后的“语句组织与整合”如根据query与相关检索结果的拼接生成针对query同时蕴含检索结果的通顺回复。不同种类和规模的LLM其语句组织能力差异明显。因此LLM选择时会面临 模型大小效果推理延迟性能之间的平衡。

4.1.2 SFT训练

如果领域内有批量的QA数据可以选择对LLM进行领域相关的精调SFT考虑到原始LLM已具备了需要的语句组织生成能力这一步不是必须的。可以根据具体场景结合优缺点判断

优点SFT可以提升LLM在领域内的知识能力使其能更好地理解和处理领域相关的知识、术语和上下文同时对一些检索库中没有相关内容的问题具有一定的泛化回复能力。缺点SFT可能引起“灾难性遗忘”一定程度损害LLM本身的文本组织生成能力使其基于检索结果的生成效果变差。

如果选择进行SFT训练可以按照以下步骤准备数据并使用开源的 DeepSpeed-Chat 框架进行SFT训练。

训练样本示例以ChatGLM2的prompt格式为例
[Round 1]问弹外VVP用户读写Hologres导致JDBC连接数暴涨答报错原因现在VVP Hologres Connector读写Hologres除了Binlog默认都使用了JDBC模式也就是HoloClient当并发数很高的情况下会占用很多连接。解决办法可以加上参数useRpcMode  true 切回至Rpc模式。
从Github拉取代码并安装运行环境
git clone  DeepSpeedExamples/applications/DeepSpeed-Chatpip install -r requirements.txt
在 training/utils/data/ 目录下的 data_utils.py 和 raw_datasets.py 文件中新增自定义数据集训练样本示例如上在 training/step1_supervised_finetuning/training_scripts 目录下新建训练脚本langchain_sft.sh
OUTPUT/path/to/saveZERO_STAGE2if [ $OUTPUT   ]; then    OUTPUT./outputfiif [ $ZERO_STAGE   ]; then    ZERO_STAGE3fimkdir -p $OUTPUTdeepspeed main.py \   --data_path /path/to/data \   --data_split 10,0,0 \   --model_name_or_path /path/to/chatglm2-6b \   --per_device_train_batch_size 4 \   --per_device_eval_batch_size 16 \   --max_seq_len 2048 \   --learning_rate 9.65e-7 \   --weight_decay 0. \   --num_train_epochs 10  \   --save_per_epoch 5 \   --gradient_accumulation_steps 4 \   --lr_scheduler_type cosine \   --num_warmup_steps 100 \   --seed 1234 \   --gradient_checkpointing \   --zero_stage $ZERO_STAGE \   --deepspeed \   --output_dir $OUTPUT \   |& tee $OUTPUT/training.log
执行sh脚本开始训练。
cd training/step1_supervised_finetuning/bash training_scripts/langchain_sft.sh
4.1.3 效果评估

训练结束后可以对SFT后的LLM进行效果评估。传统的NLP文本评价指标包括基于统计的指标以及基于BERT等预训练模型的指标。基于统计的方法大多基于N-gram词重叠率如 BLEU (Papineni等人2002年)、ROUGE (Lin2004年)、METEOR (Banerjee等人2005年) 等被广泛应用于机器翻译和文本摘要等场景。基于预训练模型的指标以 BERTScore (Zhang等人2019年) 为代表通过句子相似度计算进行评估鲁棒性较好。

不过这些传统评估metrics都无法全面衡量出LLM的能力效果。目前主流的LLM评估方法是使用覆盖各类常见任务的人类试题来检验模型是否具备世界知识world knowledge以及解题能力problem solving。当前常见的中文LLM Benchmark包括CMMLU、MMCU、C-Eval、GaoKao、SuperCLUE等英语/多语言LLM Benchmark包括MMLU、HELM、OpenLLM、OpenCompass、MT-bench、AGIEval、BIG-bench等。

下面以 CMMLU 为例展示其推理与评估步骤。CMMLU是一个综合性的中文评估基准专门用于评估语言模型在中文语境下的知识和推理能力。它涵盖了从基础学科到高级专业水平的67个主题11528道多项选择题包括需要计算和推理的自然科学需要知识的人文科学和社会科学以及需要生活常识的中国驾驶规则等。此外CMMLU中的许多任务具有中国特定的答案可能在其他地区或语言中并不普遍适用因此它是一个完全中国化的中文测试基准。

从Github拉取代码与数据集
git clone  CMMLU/script
修改 CMMLU/script/chatglm.sh 中的模型路径为微调后的模型checkpoint保存路径
...    --model_name_or_path /path/to/sft_checkpoint \...
运行 chatglm.sh 脚本模型在各项子领域zero-shot、one-shot、...、five-shot上的分数将会输出在终端屏幕上。
bash llama2_7b_chat.sh

4.2 Prompt工程

对于不同的专业垂直领域可以采取不同的prompt策略以最大化外部知识对LLM的辅助作用。LLM生成时最主要的问题在于其不可控性包括LLM无视query与检索结果“自由发挥”或LLM无法精准复现出检索结果中的关键信息如超链接、代码等。我们以下述几个场景为例展示prompt工程构建思路。

场景一超链接精准提取

方案一Prompt控制

思路对检索出来的知识若内部有网页链接的将其尽可能提取出来单独将其额外作为知识在此强调。同时若知识存在网页会在prompt中增加requirement强调回答的时候“上方提供的知识中可供参考的链接有什么”。需前调上方知识出现的链接以免出现别的链接。

import reprompt  你是一位智能小助手请根据下面我所提供的相关知识对我提出的问题进行回答。回答的内容必须包括其定义、特征、应用领域以及相关网页链接等等内容同时务必满足下方所提的要求\n 相关知识如下\nfor i in range(len(contents)):    if http in contents[i]:        prompt  str(i  1)  、该知识中包含网页链接!  \n  contents[i] 。 \n  知识中包含的链接如下:         pattern  r([^])(https?://\S?)(?\s|$)        matches  re.findall(pattern, contents[i])        # 将链接和对应名称内容存储到列表中        links  [(name.strip(), url) for name, url in matches]        for name, url in links:            # print(name,name)            # print(url,url)            prompt   \n  name  :  url  \n            else:        prompt  str(i  1)  、  contents[i]  \nif http in prompt:    requirement   回答的内容要求:若提供的知识中存在“网页链接”则必须将“网页链接”准确无误的输出。不需要输出知识库以外的网页链接     prompt  \n  requirement  \n  \n 问题是1.  query_text[0]    2. 上方提供的知识中可供参考的链接有什么  \nelse:    prompt  \n 问题是  query_text[0]  \n
效果展示

query: 为什么同一个odps sql任务运行时间差异很大

向量检索结果

odps的sql运行时间长怎么办:如何处理慢作业的常见问题_云原生大数据计算服务 MaxCompute-阿里云帮助中心

prompt优化前结果链接乱贴

以下是一些可能有助于解决SQL任务运行时间差异问题的建议

1. 使用数据库连接池 <

2. 使用索引 <

3. 优化SQL代码 <

4. 增加ODPS集群资源 <

prompt优化后结果链接精准透出

1. 同一个ODPS SQL任务,运行时间差异很大,可能是由于以下原因:

- 数据库连接时间:数据库连接时间会直接影响SQL任务的执行时间,如果数据库连接时间较长,则整个SQL任务的执行时间也会相应增加。

- 查询时间: SQL查询时间也会对任务的执行时间产生影响。如果查询时间较长,则整个SQL任务的执行时间也会相应增加。

- 输出数据量:如果SQL任务需要输出大量的数据,则输出数据量也会对任务的执行时间产生影响。

2. 上方提供的知识中可供参考的链接有:

-odps的sql运行时间长怎么办:如何处理慢作业的常见问题_云原生大数据计算服务 MaxCompute-阿里云帮助中心

案二Map reduce

借鉴LangChain官方文档中 Map reduce 思想。

思路对于一个query从矢量数据库从检索出n条knowledges将每条知识与query单独输入LLM中得到仅对这个知识下的answer最后将n个answer一同merge作为输出的结果。

场景二关键信息精准还原生成

输入query后对于retrieve到的知识的长度先做一个检查可设定一个threshold

若长度在100个字以内的就直接让大模型对知识进行打印否则改变prompt的形式让其输出变得可控 首先先判断知识是否存在http 若有http则需要LLM准确打印出http同时结合两者回答若无http围绕LLM自身知识与知识库内容进行回答

若没找到知识则直接依靠LLM自身知识进行回答

def process(self, db_res):    contents  []    for reply in db_res:        contents.append(reply)    if len(contents) >1:        for i in range(len(contents)):            if len(contents[i]) < 100:                prompt  你是一位智能小助手请将我提供的内容的原文直接打印出来不需要你做别的任何解释与分析\n 内容如下\n  contents[i]            else:                if http in contents[i]:                    prompt  你是一位智能小助手请针对我提出的问题进行回答。  \n\                        为了帮助你更好的解答这个问题对于该问题本地的知识库检索到了相关的标准答案。 \n 知识库中的标准答案是如下:\n                    prompt  str(i  1)  、  contents[i]  。\n  现在要求你结合知识库的标准答案与自身知识对提出的问题:\n  query,进行回答。\                        回答的内容要求如下1.请控制你回答的内容紧密的围绕知识库中的标准答案进行回答\n 2.知识库中涉及网页链接请将该网页链接正确无误的打印出来                else:                    prompt  你是一位智能小助手请针对我提出的问题进行回答。  \n\                        为了帮助你更好的解答这个问题对于该问题本地的知识库检索到了相关的标准答案。 \n 知识库中的标准答案是如下:\n                    prompt  str(i  1)  、  contents[i]  。\n  现在要求你结合知识库的标准答案与自身知识对提出的问题:\n  query,进行回答。\                        回答的内容要求如下1.请控制你回答的内容紧密的围绕知识库中的标准答案进行回答    else:        prompt  你是一位智能小助手请根据你自身的知识储备对我提出的若干问题进行回答。\n  \n  回答以下问题: \n  query 
效果展示

query: odps中删除一个项目

向量检索结果

odps常见咨询【如何删除项目】:删除空间 步骤如下: 运维平台 --> 我的项目 --> 更多 --> 项目下线 请点击 [运维平台](

prompt优化前结果关键信息不完整超链接未透出

要在ODPS中删除一个项目,请按照以下步骤操作:

登录ODPS控制台并登录您的账户。导航到“我的项目”页面,选择“项目列表”选项卡。找到要删除的项目并点击“下线”按钮。在弹出的提示框中,选择“确认下线”选项,即可删除该项目。

请注意,删除一个项目后,它将不再存在于您的ODPS账户中,而且所有相关数据和项目文件都将被永久删除。因此,在删除项目之前,请确保备份任何重要数据。

prompt优化后结果关键信息完整超链接准确

针对odps中删除一个项目的问题根据知识库中的标准答案可以得知删除项目的步骤如下

打开odps的运维平台并登录账户。在导航栏中点击“我的项目”进入项目列表页面。在项目列表页面中找到要删除的项目并点击“更多”按钮。在弹出的选项中选择“项目下线”即可删除该项目。

知识库中涉及网页链接为

场景三代码&超链接精准提取

若输入query后检索到答案对于retrieve到的知识的长度先做一个检查可设定一个threshold

若长度在100个字以内的就直接让大模型对知识进行打印否则改变prompt的形式 若先判断知识是否存在“命令” 有命令则需要LLM准确打印出code同时结合知识库中的标准答案两者回答 若判断知识是否存在“http” 有“http”, 则需要LLM准确打印出http同时结合知识库中的标准答案两者回答 否则若无http与命令则LLM结合自身知识与标准答案进行回答

若没找到知识则直接依靠LLM自身知识进行回答

def process(self, db_res):    contents  []    for reply in db_res:        contents.append(reply)    if len(contents) >1:        for i in range(len(contents)):            if len(contents[i]) < 100:                prompt  你是一位智能小助手请将我提供的内容的原文直接打印出来不需要你做别的任何解释与分析\n 内容如下\n  contents[i]            else:                if 命令 in contents[i]:                    prompt  你是一位智能小助手请针对我提出的问题进行回答。  \n\                        为了帮助你更好的解答这个问题对于该问题本地的知识库检索到了相关的标准答案。 \n 知识库中的标准答案是如下:\n                    prompt  str(i  1)  、  contents[i]  。\n  现在要求你结合标准答案与自身知识对提出的问题:\n  query,进行回答。\                        \n回答的内容要求如下\n1.请控制你回答的内容请紧密的围绕标准答案进行回答\n2.知识库中涉及命令行和代码请将每一行命令行和代码正确无误的打印出来                elif http in contents[i]:                    prompt  你是一位智能小助手请针对我提出的问题进行回答。  \n\                        为了帮助你更好的解答这个问题对于该问题本地的知识库检索到了相关的标准答案。 \n 知识库中的标准答案是如下:\n                    prompt  str(i  1)  、  contents[i]  。\n  请结合标准答案与自身知识对以下提出问题进行回答:\n  1.  query \                        \n2.标准答案中存在网页链接要求你将该网页链接地址正确无误的打印出来                else:                    prompt  你是一位智能小助手请针对我提出的问题进行回答。  \n\                        为了帮助你更好的解答这个问题对于该问题本地的知识库检索到了相关的标准答案。 \n 知识库中的标准答案是如下:\n                    prompt  str(i  1)  、  contents[i]  。\n  现在要求你结合标准答案与自身知识对提出的问题:\n  query,进行回答。\                        \n回答的内容要求如下\n1.请控制你回答的内容请紧密的围绕知识库中的标准答案进行回答    else:        prompt  你是一位智能小助手请根据你自身的知识储备对我提出的若干问题进行回答。\n  \n  回答以下问题: \n  query 
效果展示

query: odps报错任务运行如何调整优先级

向量检索结果

odps如何设置作业优先级:设置作业优先级的方式如下运行......命令示例如下。set odps.instance.priorityvalues;//values取值为0~9。运行MaxCompute......命令示例如下。bin/odpscmd --configxxx --projectxxx --instance-priorityx -e 通过Java SDK设置作业优先级......命令示例如下。import com.aliyun.odps.Instance;import com.aliyun.odps.LogView;import com.aliyun.odps.Odps;import com.aliyun.odps.OdpsException;import com.aliyun.odps.account.Account;import com.aliyun.odps.account.AliyunAccount;import com.aliyun.odps.task.SQLTask;public class OdpsPriorityDemo {public static void main(String args[]) throws OdpsException {Account account new AliyunAccount(accessId,accessKey);Odps odps new Odps(account);String odpsUrl // 公共云URL。odps.setEndpoint(odpsUrl);odps.setDefaultProject(xxxxxxxxxx);SQLTask task new SQLTask();task.setName(adhoc_sql_task_1);task.setQuery(select count(*) from aa;);Instance instance odps.instances().create(task, 5); // 5为作业优先级。LogView logView new LogView(odps);System.out.println(logView.generateLogView(instance, 24)); // 打印Logview用于查看Instance执行状态非必须。instance.waitForSuccess(); // 等待Instance执行完成非必须。}}通过DataWorks......命令示例如下。set odps.instance.priorityx;//x为优先级取值。

prompt优化前结果代码不完整

如果odps任务运行时出现报错可以尝试以下方式调整作业优先级

在odps客户端中进入Project空间设置作业优先级。可以通过以下命令设置MaxCompute作业的优先级

set odps.instance.priorityvalues; //values取值为0~9

其中values的取值范围为0~9可以根据具体需求设置。

或者您也可以通过DataWorks的基线管理功能设置作业优先级。该方式常用于保障某个周期性作业以及其上游作业优先产出数据。您可以通过基线管理功能集中设置整条数据链路上各个作业的优先级无需单独处理每个作业。

在DataWorks中您可以通过以下命令设置作业优先级set odps.instance.priorityx; //x为优先级取值

其中x为优先级取值可以设置为1、3、5、7或8数值越大优先级越高。当您通过DataWorks的基线管理功能设置MaxCompute作业优先级时MaxCompute作业优先级9-DataWorks基线优先级。

请注意以上方式可能会影响任务的执行时间和优先级需要根据具体情况进行调整。

prompt优化后结果代码完整透出

针对odps报错任务运行如何调整优先级的问题根据本地知识库的检索可以得出以下解答

如果odps任务运行时遇到错误可以通过重新运行任务来解决。在重新运行任务之前可以尝试调整任务优先级以便任务能够更优先地运行。具体的调整方式如下

- 在odps客户端中运行以下命令行set odps.instance.priorityvalues; //values取值为0~9设置作业优先级。

- 然后运行MaxCompute客户端并进入Project空间设置作业优先级。该方式常用于设置临时查询作业的优先级。通过这种方式可以确保任务在出现错误时能够得到更快的处理。

如果odps任务运行时遇到错误可以尝试使用以下代码来调整任务优先级
import com.aliyun.odps.Instance;import com.aliyun.odps.LogView;import com.aliyun.odps.Odps;import com.aliyun.odps.OdpsException;import com.aliyun.odps.account.Account;import com.aliyun.odps.account.AliyunAccount;import com.aliyun.odps.task.SQLTask;public class OdpsPriorityDemo {    public static void main(String[] args) throws OdpsException {        Account account  new AliyunAccount(accessId,accessKey);        Odps odps  new Odps(account);        String odpsUrl   // 公共云URL。        odps.setEndpoint(odpsUrl);        odps.setDefaultProject(xxxxxxxxxx);        SQLTask task  new SQLTask();        task.setName(adhoc_sql_task_1);        task.setQuery(select count(*) from aa;);        Instance instance  odps.instances().create(task, 5); // 5为作业优先级。        LogView logView  new LogView(odps);        System.out.println(logView.generateLogView(instance, 24)); // 打印Logview用于查看Instance执行状态非必须。        instance.waitForSuccess(); // 等待Instance执行完成非必须。    }} ”

以上代码可以在odps任务运行时动态调整任务优先级确保任务能够更优先地运行。

4.3 推理部署 4.3.1 PAI-EAS部署在线服务

模型在线服务 PAI-EAS (Elastic Algorithm Service) 是一种模型在线服务平台可支持您一键部署模型为在线推理服务或AI-Web应用。它提供的弹性扩缩容和蓝绿部署等功能可以支撑您以较低的资源成本获取高并发且稳定的在线算法模型服务。此外PAI-EAS还提供了资源组管理、版本控制以及资源监控等功能方便您将模型服务应用于业务。PAI-EAS适用于实时推理、近实时异步推理等多种AI推理场景并具备自动扩缩容和完整运维监控体系等能力。

在LLM检索增强链路中一般需要部署2个PAI-EAS在线服务

LangChain主链路服务其中会调用向量检索对用户query与向量检索后的结果进行拼接添加prompt工程并调用LLM在线推理服务得到回复后处理后返回给用户LLM在线推理服务根据query和检索结果拼好的prompt输入LLM后返回结果

部署PAI-EAS在线服务需要登陆 PAI控制台进入PAI EAS模型在线服务页面根据需求配置相关参数完成部署后即可得到调用地址url与token。

4.3.2 BladeLLM模型加速与流式输出

BladeLLM 是阿里云PAI平台提供的大模型部署框架支持主流LLM模型结构并内置模型量化压缩、 BladeDISC编译等优化技术用于加速模型推理。使用BladeLLM的预构建镜像能够便捷地在PAI-EAS平台部署大模型推理服务。

BladeLLM可以在PAI-EAS上很方便地进行部署。以7B参数规模的模型为例使用fp16数值精度推理情况下可以使用 A10 (24GB) 或 V100 (32GB) 规格的单卡GPU实例。服务启动完成可通过如下方式调用服务流式地获取生成文本

import jsonfrom websockets.sync.client import connectwith connect(ws://localhost:8081/generate_stream) as websocket: prompt  Whats the capital of Canada? websocket.send(json.dumps({        prompt: prompt,        sampling_params: {                temperature: 0.9,                top_p: 0.9,                top_k: 50            },        stopping_criterial:{max_new_tokens: 100}}))while True:msg  websocket.recv() msg  json.loads(msg) if msg[is_ok]:if msg[is_finished]: breakprint(msg[tokens][0][text], end, flushTrue) print()    print(- * 40)

线上测试使用BladeLLM加速后的链路延时RT可加速约40%。同时支持流式文本生成大幅减少用户等待时间提升用户体验。

五、WebUI Demo

以下展示根据上述模块化搭建 LangChain 检索增强 LLM 问答的 WebUI Demo每个模块均在前端中展示并可进行自定义配置。

5.1 参数配置界面

支持自定义embedding模型、自选向量检索库与参数配置、在线EAS服务参数配置。

5.2 用户知识上传建库

切换到Upload选项卡中按照界面操作指引上传知识库文件然后单击Upload。

以Hologres为例上传成功后您可以在Hologres数据库中查看写入的数据和向量等信息。具体操作请参见表。

5.3 多种模式问答

切换到Chat选项卡中支持 1) 纯向量检索2) 纯LLM生成3) LLM检索增强 三种不同模式。选择不同的查询模式推理效果如下。

六、落地案例 阿里云计算平台大数据产品智能问答系统 传统方案

计算平台中包含了多个大数据产品这些产品在提供各种能力的同时也带来了大量答疑问题。传统的方案是基于Elasticsearch进行信息检索主要存在两个问题

1、检索面向关键词缺乏对上下文的理解。

2、强依赖于知识库的建设质量需要投入大量人力进行语言交互等细节上的审核工作。

优化方案

在本项目中我们致力于借助大模型的知识理解和涌现能力打造面向计算平台大数据产品的智能问答系统从而高效且准确地对用户问题进行答疑降低人工答疑的成本。为了解决在强事实性要求的情况下大模型容易生成“幻觉”的问题我们参考了LangChain提供的知识库问答方案在问题输入时给模型提供相关知识和限制使其聚焦在特定的问题中从而给出更符合要求的回答同时针对性地使用高质量的业务数据对模型参数进行全量微调让模型掌握更充分的背景知识。整体系统框架如下

业务结果

在各算法模块选定和全工程链路落地实现后我们推动了后续两个阶段的业务试点与效果评估。

研发小二试用

在第一阶段中让研发小二在解决实际问题的过程中试用模型并给出相应反馈辅助我们针对性地对模型进行调优。

在一个月的迭代改进中我们将问题归为检索问题、模型总结问题、知识缺失 三类。面向不同类别的问题我们分别采取了针对性的措施如调整检索模块修改prompt模版加入规则过滤补充知识库内容等最终经过一个多月的攻坚小二采纳率从最初的不到20%提升到了70%。

线上灰度结果

在第二阶段中灰度上线通过真实线上数据变化直观地对模型结果进行检验。主要入口包括

1) 大数据技术服务助手

2) 研发小蜜答疑机器人

数据表明在灰度上线的渠道内相比于传统的检索式问答拦截率提升了10%有效地降低了大数据产品的人工答疑成本。

联系我们

我们是阿里云智能-计算平台事业部-机器学习PAI算法团队在大语言模型相关的各个方向如LLM检索增强、Continue pretrain、SFT、RLHF、大模型评测、轻量化训练推理等方向上均有技术积累。欢迎对大语言模型相关应用有兴趣的团队一起合作联系我们共建各类有价值有落地的应用场景。钉钉群号是 42250004375。

标签:
声明:无特别说明,转载请标明本文来源!