微信扫码
与创始人交个朋友
我要投稿
对于技术人来讲,这无疑是让我们激动的,热血沸腾、心潮澎湃的。像漆黑的夜里发现了光,像无垠的荒漠看见了水,像迷路的马儿找到了路。
当然,在旅途中也绽放了一系列令人鼓舞的成就。我们汇聚了一批心怀共鸣的同行者,共同打造了一个近 10k+ Star 的开源社区,我们的研究成果以 Paper 的方式与世界共享,社区获得了一些奖项,同时也获得了业界和你们的认可与肯定。
在当前的大模型时代下,普遍的观点认为开发一个基于大模型的应用只需要几句简单的 Prompt,甚至也都在炒作“ Prompt 工程师”的概念。然而,对于专注于具体垂域领域应用落地的同学们,情况并非这么简单。超越基础的角色扮演游戏,搞点没多大用处的创作之外,我们不禁要问:仅凭几句提示语(Prompt)真的足够吗?在通用大模型与垂域场景之间的天然的信息鸿沟,真的能视而不见吗?简单的微调与加训真的就能解决所有的问题吗?RAG 能搞定一切吗?我想答案是不能,至少对目前的大模型底座来讲,是不能的。
这也解释了为何在开发针对垂直领域的应用时,我们会感到困难重重。经过长达半年的不懈努力,仍然看不到多少实用性强的应用实际落地。除了各个平台上看到像 Copilot 这样的辅助工具外,其他切实可行的落地场景屈指可数。为什么会这样呢?原因可能是技术上的断层。新一代以大模型为大脑的应用开发模式已逐渐成为必然,但只有“大脑”还不够,我们还需要“四肢”,即能够支撑大脑的实际操作能力。大脑与四肢之间如何联动,包括大脑如何不断掌握新的知识,这些都是亟待解决的问题。
在大模型领域,数据集的问题想必已经成为一个普遍和棘手的挑战,而且预计这个挑战在未来只会越来越头疼,尤其是那些数据集资源更加匮乏的垂域。数据集的构建应该被视为一项长远和前瞻性任务,而作为三年、五年计划一点都不为过。
DB-GPT 项目一直都走得比较坚定。在今年4月初我们定下来整个技术架构到现在,都没有多大的变化。我们一直坚持想做一件事就是: "Revolutionizing Database Interactions with Private LLM Technology",即"用大模型技术定义数据库下一代交互方式"。
通用模型能解决所有问题吗?需不需要领域模型?面向未来,多模型之间是怎么协作交互的?这几个问题我们一直都在思考。但截至目前,跟我们5个月之前的认知也没太大的变化,那就是以后应用落地需要三层的大模型交互架构。如下图所示,从上往下依次是:
通用大语言模型(> 100B)
领域大语言模型(10~70B)
为什么要有这样的思考?因为我们发现,自然语言的理解、语义分析等远比我们想象的复杂,即使今天有非常多的开源模型都可以进行自然语言对话。但是能够通过确定的 Prompt 拿到确定结果的模型,少之又少。只有ChatGPT、GPT-4 这样的模型有较好的表现,通用大语言模型无论是体量还是入门门槛都非常高,所以天然决定了这一层的生意会变成寡头,最后只能活下来效果最好的极少数几家。而这一层的迭代是符合数据飞轮理论,即谁的效果越好,先发优势越大,谁的模型就能得到更好的训练,形成增长飞轮。
引入领域层模型之后,为何还需要第三层工具模型?这主要是出于对高精度与成本的需求。针对非常细分的场景去做任务的时候,通常不太需要模型掌握太多的泛化或者推理的能力。相反,我们需要的是模型能以最低成本可靠地完成某一任务的能力。以生产线上的工人为例,我们不期望工人去理解或深入推敲公司的战略方向,而是希望他们能高效率、高质量地执行当前的任务。同样地,工具模型的职能是专注于某一特定操作或功能,执行预定的任务,而无需处理与任务无关的复杂推理过程。这种模型专注于特定的工艺,减少了不必要的复杂性,提升了执行的精确性,并且从成本的角度看,更加经济实惠。
下图是 DB-GPT 的架构图,整体结构比较简单。左侧是知识(RAG),右侧是工具(Agents),中间是多模型管理(SMMF),同时增加了向量存储这样的大模型记忆体,以及各类数据源,往上是一层通用的交互层面。
经过这一年的折腾与抽象,我们将 DB-GPT 未来的架构进行了分层。如下图所示,主要分为以下 7 层,自上而下分别为:
可视化层: 可视化层主要的工作是对话、交互、图表显示、可视化编排等能力。
应用层: 基于底层能力的应用构建,如 GBI 应用、ChatDB 类应用、ChatData 类应用、ChatExcel 类应用等。
服务层: 服务层主要是对外暴露的服务,比如 LLMServer、APIServer、RAGServer、dbgptserver 等
核心模块层: 核心模块主要有三个分别是,SMMF、RAGs、Agents
协议层:协议层主要是指 AWEL (Agentic Workflow Expression Language), 即智能体编排语言,是专门为大模型应用开发设计的智能体工作流表达式语言。
训练层: 训练层会主要关注 Text2SQL、Text2DSL、Text2API 方向的微调,提供标准的微调脚手架。
运行环境: 运行环境是指整个框架的运行在什么环境当中,我们后期会优先支持基于 Ray 与 Kubernetes 的环境。
接下来对其中一些关键模块做一些较为详细的介绍。
前面我们有提到说面向未来是通用大模型、领域模型、小模型一起交互协作的。 那就特别需要对模型进行管理,而且模型需要是一个个随时可调用的服务。在我们的框架里面叫 Service-oriented Multi-model Management Framework (SMMF) 服务化多模型管理框架。多模型管理框架的本质其实就是模型服务的 Serverless 化。
SMMF 具体如上图所示: 最上层对应服务与应用层(如 DB-GPT WebServer、Agents 系统、应用等)。下一层是模型部署框架层,这层包含了对应用层提供模型服务的 APIServer 和 Model Handle、整个部署框架的元数据管理和控制中心 Model Controller 和与推理框架和底层环境直接对接的 Model Worker。再下一层是推理框架层,这层包含了 vLLM、 llama.cpp 和 FastChat (由于 DB-GPT 直接使用了 FastChat 的推理接口,这里我们将 FastChat 也归为推理框架),大语言模型( Vicuna、Llama、Baichuan、ChatGLM )等部署在推理框架中。 最下面一层则是实际部署环境,包括 Kubernetes、Ray、AWS、阿里云和私有云等。
为了能够让客户端无感使用各类模型,我们无缝兼容了 OpenAI 的 SDK,即通过一套标准的 SDK 即可无缝使用各类大语言模型。
import openai
openai.api_key = "EMPTY"
openai.api_base = "http://127.0.0.1:8100/api/v1"
model = "vicuna-13b-v1.5"
completion = openai.ChatCompletion.create(
model=model,
messages=[{"role": "user", "content": "hello"}]
)
# print the completion
print(completion.choices[0].message.content)
关于此部分内容更详细的介绍,可以参考官方文档内容。
MS-RAG 指的是多文档检索增强能力,这部分也是 DB-GPT 中的一个基础核心模块。 当前 MS-RAG 实现了基本的增强检索的操作,并对文档、多源数据检索场景做了非常多的定制优化。整个流程中涵盖了知识构建、知识检索、答案生成全链路的能力。关于此部分更细节的内容,我这里暂且按下不表,后面会有专门的文章进行介绍。
Agents 也是 DB-GPT 框架中一个非常核心的模块,我们在 DB-GPT 早期的 Agents 框架版本中,进行了全新构建,引入了类 AutoGen 当中的多角色协同理念。同时为了更好地在数据领域落地,我们提出了数据驱动的 Agents 理念,在实际的使用场景中,每个 agents 会有一个 DataFrame 上下文。结合此上下文可以对 agents 做前后置数据一致性校验与订正。当前升级版本的代码经过我们最近紧张的开发之后,也已经进入到测试阶段,相信不久后就会与大家见面。 我们也会提供更多的介绍说明与使用案例。
AWEL(Agentic Workflow Expression Language)是一套专为大模型应用开发设计的智能体工作流表达语言,它提供了强大的功能和灵活性。通过 AWEL API 您可以专注于大模型应用业务逻辑的开发,而不需要关注繁琐的模型和环境细节,AWEL 采用分层 API 的设计, AWEL 的分层 API 设计架构如下图所示:
AWEL 在设计上分为三个层次,依次为算子层、AgentFrame 层以及 DSL 层,以下对三个层次做简要介绍。
AWEL 初步的版本已经在 V0.4.2 发布,我们内置提供了一些使用样例。
## 源码位置 examples/awel/simple_rag_example.py
with DAG("simple_rag_example") as dag:
trigger_task = HttpTrigger(
"/examples/simple_rag", methods="POST", request_body=ConversationVo
)
req_parse_task = RequestParseOperator()
# TODO should register prompt template first
prompt_task = PromptManagerOperator()
history_storage_task = ChatHistoryStorageOperator()
history_task = ChatHistoryOperator()
embedding_task = EmbeddingEngingOperator()
chat_task = BaseChatOperator()
model_task = ModelOperator()
output_parser_task = MapOperator(lambda out: out.to_dict()["text"])
(
trigger_task
req_parse_task
prompt_task
history_storage_task
history_task
embedding_task
chat_task
model_task
output_parser_task
)
位运算会将整个过程以 DAG 的形式编排。
af = AgentFream(HttpSource("/examples/run_code", method = "post"))result = (af.text2vec(model="text2vec").filter(vstore, store = "chromadb", db="default").llm(model="vicuna-13b", temperature=0.7).map(code_parse_func).map(run_sql_func).reduce(lambda a, b: a + b))result.write_to_sink(type='source_slink')
DSL 采用ANTLR4 / Lark解析器
CREATE WORKFLOW RAG AS
BEGIN
DATA requestData = RECEIVE REQUEST FROM
http_source("/examples/rags", method = "post");
DATA processedData = TRANSFORM requestData USING embedding(model = "text2vec");
DATA retrievedData = RETRIEVE DATA
FROM vstore(database = "chromadb", key = processedData)
ON ERROR FAIL;
DATA modelResult = APPLY LLM "vicuna-13b"
WITH DATA retrievedData AND PARAMETERS (temperature = 0.7)
ON ERROR RETRY 2 TIMES;
RESPOND TO http_source WITH modelResult
ON ERROR LOG "Failed to respond to request";
END;
作为 DB-GPT 项目的一部分,我们提供了 Text2SQL 微调相关的代码,目前已经按照独立的 pypi 包发布,可以直接安装进行使用。
pip install dbgpt_hub
查看模型基线
from dbgpt_hub.baseline import show_scoresshow_scores()
微调
from dbgpt_hub.data_process import preprocess_sft_data
from dbgpt_hub.train import start_sft
from dbgpt_hub.predict import start_predict
from dbgpt_hub.eval import start_evaluate
data_folder = "dbgpt_hub/data"
data_info = [
{
"data_source": "spider",
"train_file": ["train_spider.json", "train_others.json"],
"dev_file": ["dev.json"],
"tables_file": "tables.json",
"db_id_name": "db_id",
"is_multiple_turn": False,
"train_output": "spider_train.json",
"dev_output": "spider_dev.json",
}
]
train_args = {
"model_name_or_path": "codellama/CodeLlama-13b-Instruct-hf",
"do_train": True,
"dataset": "example_text2sql_train",
"max_source_length": 2048,
"max_target_length": 512,
"finetuning_type": "lora",
"lora_target": "q_proj,v_proj",
"template": "llama2",
"lora_rank": 64,
"lora_alpha": 32,
"output_dir": "dbgpt_hub/output/adapter/CodeLlama-13b-sql-lora",
"overwrite_cache": True,
"overwrite_output_dir": True,
"per_device_train_batch_size": 1,
"gradient_accumulation_steps": 16,
"lr_scheduler_type": "cosine_with_restarts",
"logging_steps": 50,
"save_steps": 2000,
"learning_rate": 2e-4,
"num_train_epochs": 8,
"plot_loss": True,
"bf16": True,
}
predict_args = {
"model_name_or_path": "codellama/CodeLlama-13b-Instruct-hf",
"template": "llama2",
"finetuning_type": "lora",
"checkpoint_dir": "dbgpt_hub/output/adapter/CodeLlama-13b-sql-lora",
"predict_file_path": "dbgpt_hub/data/eval_data/dev_sql.json",
"predict_out_dir": "dbgpt_hub/output/",
"predicted_out_filename": "pred_sql.sql",
}
evaluate_args ={
"input": "./dbgpt_hub/output/pred/pred_sql_dev_skeleton.sql",
"gold": "./dbgpt_hub/data/eval_data/gold.txt",
"gold_natsql": "./dbgpt_hub/data/eval_data/gold_natsql2sql.txt",
"db": "./dbgpt_hub/data/spider/database",
"table": "./dbgpt_hub/data/eval_data/tables.json",
"table_natsql": "./dbgpt_hub/data/eval_data/tables_for_natsql2sql.json",
"etype": "exec",
"plug_value": True,
"keep_distict": False,
"progress_bar_for_each_datapoint": False,
"natsql": False,
}
preprocess_sft_data(
data_folder = data_folder,
data_info = data_info
)
start_sft(train_args)
start_predict(predict_args)
start_evaluate(evaluate_args)
更多信息可以参考我们的开源代码
所有用户,相同 prompt (内容、input length 和 output length 相同),同一时间发起推理请求,在同一硬件条件下的首字延迟、推理延迟和吞吐量。
GPU:NVIDIA A100-PCIE-40GB * 1
CPU: Intel Xeon Processor (Skylake, IBRS) 40核80线程 2992.953 MHz
内存:629 GB
硬盘:1T HDD
推理框架:vllm 和 huggingface transformers
模型:Qwen-7b-Chat、Qwen-14b-Chat
VLLM:
HG:
Benchmark代码地址:
https://github.com/eosphoros-ai/DB-GPT/blob/main/dbgpt/util/benchmarks
async def run_model(wh: WorkerManager) -> None:
global result_csv_file
if not result_csv_file:
result_csv_file = get_result_csv_file()
if os.path.exists(result_csv_file):
now = datetime.now()
now_str = now.strftime("%Y-%m-%d")
os.rename(result_csv_file, f"{result_csv_file}.bak_{now_str}.csv")
for parallel_num in parallel_nums:
for input_len, output_len in zip(input_lens, output_lens):
try:
await run_batch(
wh, input_len, output_len, parallel_num, result_csv_file
)
except Exception:
msg = traceback.format_exc()
logging.error(
f"Run benchmarks error, input_len: {input_len}, output_len: {output_len}, parallel_num: {parallel_num}, error message: {msg}"
)
if "torch.cuda.OutOfMemoryError" in msg:
return
sys.exit(0)
async def run_batch(
wh: WorkerManager,
input_len: int,
output_len: int,
parallel_num: int,
output_file: str,
):
tasks = []
prompt = read_prompt_from_file("11k")
if model_type == "vllm":
max_input_str_len = input_len
if "baichuan" in model_name:
# TODO prompt handle first
max_input_str_len *= 2
prompt = prompt[-max_input_str_len:]
# Warmup first
params = build_param(input_len, output_len, prompt, system_prompt="")
await wh.generate(params)
for _ in range(parallel_num):
params = build_param(input_len, output_len, prompt, system_prompt="")
tasks.append(wh.generate(params))
print(
f"Begin run benchmarks, model name: {model_name}, input_len: {input_len}, output_len: {output_len}, parallel_num: {parallel_num}, save result to {output_file}"
)
start_time_ms = time.time_ns() // 1_000_000
results: List[ModelOutput] = await asyncio.gather(*tasks)
end_time_ms = time.time_ns() // 1_000_000
test_time_cost_ms = end_time_ms - start_time_ms
test_total_tokens = 0
first_token_latency_ms = 0
latency_ms = 0
gpu_nums = 0
avg_gpu_mem = 0
rows = []
for r in results:
metrics = r.metrics
if isinstance(metrics, dict):
metrics = ModelInferenceMetrics(**metrics)
print(r)
test_total_tokens += metrics.total_tokens
first_token_latency_ms += metrics.first_token_time_ms - metrics.start_time_ms
latency_ms += metrics.end_time_ms - metrics.start_time_ms
row_data = metrics.to_dict()
del row_data["collect_index"]
if "avg_gpu_infos" in row_data:
avg_gpu_infos = row_data["avg_gpu_infos"]
gpu_nums = len(avg_gpu_infos)
avg_gpu_mem = (
sum(i["allocated_memory_gb"] for i in avg_gpu_infos) / gpu_nums
)
del row_data["avg_gpu_infos"]
del row_data["current_gpu_infos"]
rows.append(row_data)
avg_test_speed_per_second = test_total_tokens / (test_time_cost_ms / 1000.0)
avg_first_token_latency_ms = first_token_latency_ms / len(results)
avg_latency_ms = latency_ms / len(results)
with open(output_file, "a", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=METRICS_HEADERS)
if f.tell() == 0:
# Fist time
writer.writeheader()
for row in rows:
row["model_name"] = model_name
row["parallel_nums"] = parallel_num
row["input_length"] = input_len
row["output_length"] = output_len
row["test_time_cost_ms"] = test_time_cost_ms
row["test_total_tokens"] = test_total_tokens
row["avg_test_speed_per_second(tokens/s)"] = avg_test_speed_per_second
row["avg_first_token_latency_ms"] = avg_first_token_latency_ms
row["avg_latency_ms"] = avg_latency_ms
row["gpu_nums"] = gpu_nums
row["gpu_mem(GiB)"] = avg_gpu_mem
writer.writerow(row)
print(
f"input_len: {input_len}, output_len: {output_len}, parallel_num: {parallel_num}, save result to {output_file}"
)
这一年围绕大模型技术展开了非常多的话题,但截止到今天,我们或许已经看到了一些技术演进的趋势。 通用大语言模型赛道玩家密布,但明年或许会迎来第一波死亡潮。 相信经过一年的折腾,绝大多数玩家也已经明白了这个赛道的烧金程度以及技术壁垒。单单靠基于公开数据集的评测打榜宣传已经不足以引起任何的浪花,拿在实际场景一测,绝大多数都会被打回原型。
对于语言模型在垂域的落地来讲也是如此,今年相信有非常多的团队都尝试了落地实践。但除了ChatGPT、GPT-4以外的模型,唯一能有较好落地的场景或许就是知识库、答疑机器人类应用了。而这些应用的落地需要投入大量的人力进行前置的知识整理与构建。在效果上要做到一个很高的准确率,所需的投入比预想的要大的多。
此外在要求高精度,如数据分析、报表生成等场景。基本还是以传统的指标模式为主。能处理的场景也非常有限。所以还有很多的工作需要去做。我们今天看到大模型带来了很多的可能,但在实际的落地上,我相信一切也才刚刚开始。"我们总是高估技术的短期效应,而低估它们的长期影响力"。是的,历史总是在重演。我们确实也看到了很多大跃进式盲目的发展模式,也遇到了一些挫折。
但我们也看到很多有意思的落地实践,比如我们社区同学基于 DB-GPT 上的一些落地探索。包括知识问答、数据对话以及通过 Agents 编排一个超长步骤的分析链路来对复杂任务进行处理的落地实践。 所以面向未来,还是需要有足够坚定的信心。
今年因为 ChatGPT 的发布,以及 LLaMA 等模型的开源,引爆了整个大模型技术赛道。经过一年的折腾实践,我们对相关的技术也有了更深层次的理解与认识。也看到了很多有趣的方向与落地实践。相信马上到来的 2024 年,我们会看到大模型在垂域场景更多的落地实践。我们非常欢迎大家能够跟我们一起交流探索,一起来定义下一代基于大模型的数据交互解决方案。最后我们是一个很有意思的社区,欢迎大家参与到我们社区中,一起探讨、交流。
53AI,企业落地应用大模型首选服务商
产品:大模型应用平台+智能体定制开发+落地咨询服务
承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2024-03-30
2024-04-26
2024-05-10
2024-04-12
2024-05-28
2024-04-25
2024-05-14
2024-07-18
2024-04-26
2024-08-13