这一年,大模型和我们

593 阅读22分钟

前言

“二九寒天, 片片飞雪。刚刚参加完无锡开放原子大会,从酒店出来。 我伸出双手紧了紧厚厚的棉衣,一只手赶紧抱在胸前蜷缩起来,另一边顺手推开了酒店的门。 刺骨的寒风像一窝蜂吹来,像夹杂着刺一样,扎在了我的脸上 —— 真疼”

刚刚经过室内火热的会议,突然遇冷,脸都有点发青。 我不知道该怎样描述这样的时刻, 但好像也正好映射了当下我们对于大语言模型技术过分的狂热。 我毫不怀疑大模型带来的技术变革会彻底改变我们以后的生产、生活。 但确实也担忧,当下某些大跃进式的盲目。 趁着年关将近,对这一年在大模型领域的思考与探索做一个总结,同时也对接下来我们的工作做一个展望。 聊一聊我们对当下技术的判断,也定一定新年我们要走的路。

这一年

自去年12月OpenAI打开大模型的潘多拉魔盒,对技术人来讲,这一年都是高光时刻。我们看到了太多的惊喜,看到了太多的可能,太多的不同,也有太多的乐趣。

与我们而言,也看到了新的方向 —— "Next Generation Data Interaction Solution with LLMs"。

是的,它就像一缕朝阳,撕开了我们对未来的想象。 相信等太阳升起,必然会映出碧海蓝天。一切的美好,你我皆可看见。

对于技术人来讲,这无疑是让我们激动的,热血沸腾、心潮澎湃的。像漆黑的夜里发现了光;像无垠的荒漠看见了水;像迷路的马儿找到了路。 

看见了,相信了,往前走就对了! 是的,这一年我们好像一直在赶路。一直在不断交流想法,编写代码,测试可行性以及与很多一起跟我们有同样信念的同学一起协作。 

当然,我们也取得了一些小小的成绩。找到了一群志同道合的伙伴,构建了一个10k+ Star的开源社区,发表了一篇Paper,获得了一些奖项,也得到了一些认可。 

嘿,嘿嘿,嘿嘿嘿, 这一年~

垂域落地痛点

眼里有光,心中有梦固然好,但也要脚下有路。 谈到大模型的落地,尤其是在垂直领域落地的时候,我相信大家都是一坛苦水,一汪眼泪。 都是咬着牙齿坚持上,扛着麻袋堵窟窿。这模型与模型之间的差距咋就这么大。😂  当客户拿着GPT-4跑出来的效果,跟你要求对等效果的开源模型私有部署落地时。心中是刀,眼里是泪。 

1.1 预期之痛

所以回过头来看,对于技术落地来讲。第一个痛点,是预期之痛。 ChatGPT与GPT-4过度拉高了用户的预期,而我们当下的开源模型或者国产模型,抑或是自己训练的模型,还与GPT-4有非常明显的差距。 当我们拿着开源模型或者是自己的模型,要构建类似长在ChatGPT或者GPT-4上的应用时,在技术底座上本身就存在天然的差距。而如果我们一定要在效果上做到对等或者超出时,随之而来的,就是针对特定场景的深度效果优化,而这些目前基本都没有通用的方法。需要一个一个去做Trick与优化。而这里带来的人力投入,远超我们预期。 

1.2 技术断层

今天我们一直在讲,大模型时代开发一个大模型应用,只需要几句简单的Prompt,甚至也都在炒作Prompt工程师的概念,但实际在垂域做落地应用的同学们。我想问一句,除了做个角色扮演,搞点没多大用处的创作之外,真的是只有几句Prompt吗? 通用大模型与垂域场景之间的天然的信息鸿沟,真的能视而不见吗? 通过微调与加训真的就能解决所有的问题吗? RAG能搞定一切吗? 我想答案是不能,至少对目前的大模型底座来讲,是不能。 所以为什么我们今天开发垂域落地的时候,会这么累。 折腾了大半年好像也没什么特别有用的应用。除了各个平台都多了一个Copilot的干扰项之外,其他可见的落地场景屈指可数。 为什么会这样呢? 我想是因为技术的断层,新一代以大模型为大脑的应用开发模式已逐渐成为必然,但只有大脑不行呀,四肢怎么长出来。脑与手之间怎么联动,包括大脑如何不断掌握新的知识,这些都是祈待解决的问题。

1.3 数据集缺失

数据集这个问题,想必所有搞大模型相关的都已经非常头疼了。我相信还会越来越头疼。尤其对于数据集更加匮乏的垂域来讲。 而数据集是需要非常前瞻性来看待的工作,作为三年、五年计划一点都不为过。 因为没有好的教材与知识,是教不出优秀的博士生的。 单单靠爬来的那些数据,顶天了也就是个本科生。 难道真的存在说,学习了本科的知识就能涌现出博士生的水平吗? 或许吧,但我祝你们好运 🍀。

1.4 时间

俗话说,十年树木,百年树人。如果大模型带来的智能真的代表了类人的智能发展过程,那一定是需要时间慢慢培养的。 而且应该是从知识、教材、方法有一套体系的。 今天我们看到很多团队在见了ChatGPT,见了LLaMA之后好像发现了打开智能的钥匙,一股脑的涌上去搞训练。模型越拉越大,智能越来越差。 真的大代表一切吗? 大或许是一个必要条件,但绝对不是充分条件。 在掌握如何通过系统化的方法,让模型效果有相对确定的预期行为之前,所有的一味求大,可能都是在作死。 

回到垂域也是一样,不同于通用Base底座模型。垂域模型一定是基于一个相对OK的底座进行加训练或者微调的。 其实这里有非常多的问题, 1. 模型底座怎么选择? 2. 微调数据集怎么准备?3. 该用什么样的方法进行训练? 而今天我们微调方面的理论体系与工具体系都还非常初级。我们都在讲微调需要高质量的数据集,那回到垂域,如何定义高质量? 我们都知道Text2SQL需要做大量的从自然语言到SQL语句的标注。但如何标注?怎样标注的数据集是在某些模型底座与方法下确定性会变好的? 

而这些都需要时间,今天我们已经看到,大模型的训练与微调已经主要是以实验为导向,即需要在大量的实验基础上来抽象背后的理论体系。 这其实跟我们传统编程的理念有巨大的不同。 无论是从确定性编程迈入智能化不确定编程的转换,还是经过大量实验来验证背后的理论思考,都需要时间。 所以我们应该有长远的计划,大模型这场仗至少要以3~5年为计划来打,尤其我们在起步晚的前提下。

DB-GPT介绍与发展计划

DB-GPT项目其实我们一直都走的比较坚定。 在今年4月初我们定下来整个技术架构到现在,都没有多大的变化。 我们一直坚持想做一件事就是: "Revolutionizing Database Interactions with Private LLM Technology"。对"用大模型技术定义数据库下一代交互方式"。 

2.1 大模型交互三层架构

通用模型能解决所有问题吗? 需不需要领域模型? 面向未来,多模型之间是怎么协作交互的? 这几个问题其实我们一直都在思考。但截至目前,跟我们5个月之前的认知也没太大的变化。 那就是以后应用落地需要三层的大模型交互架构。 如下图所示,从上往下依次是

  • 通用大语言模型(> 100B) 
  • 领域大语言模型(10~70B)
  • 工具类模型(<10B)

为什么要有这样的思考?因为我们发现,自然语言的理解、语义分析等远比我们想象的复杂,即使今天有非常多的开源模型都可以进行自然语言对话。 但是能够通过确定的Prompt拿到确定结果的模型,少之又少。 只有ChatGPT、GPT-4这样的模型有较好的表现,所以通用大语言模型无论是体量还是入门门槛都非常高,所以天然决定了这一层的生意会变成寡头,最后只能活下来效果最好的极少数几家。而这一层的迭代是符合数据飞轮理论,即谁的效果越好,先发优势越大,谁的模型就能得到更好的训练,形成增长飞轮。

再说为什么要有领域模型层? 领域模型也可以理解为垂域模型。为什么这一层必须存在? 通用大模型真的无法学会所有的领域知识吗? 答案必然是肯定的。但社会的运转不全是"效果"的好坏,还有边界与合理性。 我们看到今天无论哪一家企业都不会把自己的核心数据资产交给通用大语言模型。在模型层内做数据加密与隐私保护又基本已经宣告是伪命题。那我们怎么保护自己数据的同时又兼顾效果呢? 我的答案是引入领域模型层,将领域模型与通用模型在私有数据资产上做解耦。对内核心业务的交互全部放在领域模型层做处理,交互层还是通过通用模型去下发,在通用模型层与领域模型之间做安全与隐私防护。 

那么领域层都有了,为什么还要有第三层工具模型? 这个我的理解主要是高精度与成本。 针对非常细分的场景去做任务的时候,我们其实不太需要模型掌握太多的泛化或者推理的能力。恰恰相反,我们需要的是最低成本确定性完成某一任务的能力。比如生产线上的工人,你需要让他去理解与推敲公司的战略方向吗? 嗯,高质量完成执行就行了。

2.2 DB-GPT的架构与特点

下图是DB-GPT的架构图,整体结构比较简单。左侧是知识(RAG),右侧是工具(Agents), 中间是多模型管理(SMMF),同时增加了向量存储这样的大模型记忆体,以及各类数据源,在往上是一层通用的交互层面。 

关键特性

  • 私域问答&数据处理&RAG

支持内置、多文件格式上传、插件自抓取等方式自定义构建知识库,对海量结构化,非结构化数据做统一向量存储与检索

  • 多数据源&GBI

支持自然语言与Excel、数据库、数仓等多种数据源交互,并支持分析报告。

  • 多模型管理

海量模型支持,包括开源、API代理等几十种大语言模型。如LLaMA/LLaMA2、Baichuan、ChatGLM、文心、通义、智谱、星火等。

  • 自动化微调

围绕大语言模型、Text2SQL数据集、LoRA/QLoRA/Pturning等微调方法构建的自动化微调轻量框架, 让TextSQL微调像流水线一样方便。

  • Data-Driven Multi-Agents&Plugins

支持自定义插件执行任务,原生支持Auto-GPT插件模型,Agents协议采用Agent Protocol标准

  • 隐私安全

通过私有化大模型、代理脱敏等多种技术保障数据的隐私安全

2.3 面向未来

经过这一年的折腾与抽象,我们将DB-GPT未来的架构进行了分层。如下图所示,主要分为以下7层,自上而下以此为:

  • 可视化层: 可视化层主要的工作是对话、交互、图表显示、可视化编排等能力。
  • 应用层: 基于底层能力的应用构建,如GBI应用、ChatDB类应用、ChatData类应用、ChatExcel类应用等。
  • 服务层: 服务层主要是对外暴露的服务,比如LLMServer、APIServer、RAGServer、dbgptserver等
  • 核心模块层: 核心模块主要有三个分别是,SMMF、RAGs、Agents
  • 协议层:协议层主要是指AWEL(Agentic Workflow Expression Language), 即智能体编排语言,是专门为大模型应用开发设计的智能体工作流表达式语言。
  • 训练层: 训练层会主要关注Text2SQL、Text2DSL、Text2API方向的微调,提供标准的微调脚手架。
  • 运行环境: 运行环境是指整个框架的运行在什么环境当中,我们后期会优先支持基于Ray与Kubernetes的环境。

下面对其中一些关键模块做一些较为详细的介绍。 

2.3.1 多模型管理(SMMF)

前面我们有提到说面向未来是通用大模型、领域模型、小模型一起交互协作的。 那就特别需要对对模型进行管理,而且模型需要是一个个随时可调用的服务。在我们的框架里面叫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)

关于此部分内容更详细的介绍,可以参考文档:多模型介绍

2.3.2 MS-RAG

MS-RAG指的是多文档检索增强能力,这部分也是DB-GPT中的一个基础核心模块。 当前MS-RAG实现了基本的增强检索的操作,并对多文档、多源数据检索场景做了非常多的定制优化。整个流程中涵盖了知识构建、知识检索、答案生成全链路的能力。关于此部分更细节的内容,我这里暂且按下不表,后面会有专门的文章进行介绍。

2.3.3 Agents

      

Agents也是DB-GPT框架中一个非常核心的模块,我们在之前的DB-GPT早期的Agents框架版本中,进行了全新构建,引入了类AutoGen当中的多角色协同理念。同时为了更好的在数据领域落地,我们提出了数据驱动的Agents理念,在实际的使用场景中,每个agents会有一个DataFrame上下文。结合此上下文可以对agents做前后置数据一致性校验与订正。 当前升级版本的代码经过我们最近紧张的开发之后,也已经进入到测试阶段,相信不久后就会与大家见面。 我们也会提供更多的介绍说明与使用案例。

2.3.4 AWEL

AWEL(Agentic Workflow Expression Language)是一套专为大模型应用开发设计的智能体工作流表达语言,它提供了强大的功能和灵活性。通过 AWEL API 您可以专注于大模型应用业务逻辑的开发,而不需要关注繁琐的模型和环境细节,AWEL 采用分层 API 的设计, AWEL 的分层 API 设计架构如下图所示:

AWEL分层设计

AWEL在设计上分为三个层次,依次为算子层、AgentFrame层以及DSL层,以下对三个层次做简要介绍。 

  • 算子层

算子层是指LLM应用开发过程中一个个最基本的操作原子,比如在一个RAG应用开发时。 检索、向量化、模型交互、Prompt处理等都是一个个基础算子。 在后续的发展中,框架会进一步对算子进行抽象与标准化设计。 可以根据标准API快速实现一组算子。

  • AgentFrame层

DataFrame层将算子做进一步封装,可以基于算子做链式计算。 这一层链式计算也支持分布式,支持如filter、join、map、reduce等一套链式计算操作。 后续也将支持更多的计算逻辑。

  • DSL层

DSL层提供一套标准的结构化表示语言,可以通过写DSL语句完成AgentFrame与算子的操作,让围绕数据编写大模型应用更具确定性,避免通过自然语言编写的不确定性,使得围绕数据与大模型的应用编程变为确定性应用编程。

使用案例

AWEL初步的版本也已经在V0.4.2发布,我们内置提供了一些使用样例。

算子层API-RAG例子

源码在项目中位置 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的形式编排。 

算子层API调用模型+缓存例子

AgentFrame层API样例
af = AgentFrame(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层API样例

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;

2.3.5 Train

作为DB-GPT项目的一部分,我们提供了Text2SQL微调相关的代码,目前已经按照独立的pypi包发布,可以直接安装进行使用。

pip install dbgpt_hub

查看模型基线

from dbgpt_hub.baseline import show_scores
show_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)

更多信息可以参考我们的开源代码

2.3.6 Benchmark

简介:所有用户,相同 prompt (内容、input length 和 output length 相同),同一时间发起推理请求,在同一硬件条件下的首字延迟、推理延迟和吞吐量。

指标

1. 首字延迟(First Token Latency)

单位:毫秒

从 DB-GPT 模型部署框架接收到模型推理请求到推理框架得到第一个 token 的设计(prefill 时间 + 第一个decoding token 的时间)

延迟(Latency)

单位:毫秒

从 DB-GPT 模型部署框架接收到模型推理请求到生成完整的响应的时间。

2. 吞吐量(Throughput)

单位:tokens 每秒

DB-GPT 模型部署框架每秒中处理的所有用户和所有请求的 token 数量。

硬件配置

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代码地址: github.com/eosphoros-a…


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年,我们会看到大模型在垂域场景更多的落地实践。我们非常欢迎大家能够跟我们一起交流探索,一起来定义下一代基于大模型的数据交互解决方案。 最后我们是一个很有意思的社区,欢迎大家参与到我们社区中,一起探讨、交流。

 github.com/eosphoros-a…

附录