V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MajestySolor
V2EX  ›  机器学习

chatgpt/bingchat 这些大语言模型在进行文字回应的时候都是几个字几个字的往外蹦,这背后的原因是啥?

  •  
  •   MajestySolor · 2023-10-13 00:07:50 +08:00 · 3942 次点击
    这是一个创建于 413 天前的主题,其中的信息可能已经有所发展或是发生改变。
    53 条回复    2023-10-14 23:20:27 +08:00
    starrycat
        1
    starrycat  
       2023-10-13 00:17:16 +08:00 via Android
    学人的,因为人也是这样( doge
    noe132
        2
    noe132  
       2023-10-13 00:18:05 +08:00
    因为模型是这样工作的。会根据你的输入和已经生成的文字,来推断下面用哪个词语( token )是最合理的,然后不断重复这个步骤。
    jimages
        4
    jimages  
       2023-10-13 00:56:54 +08:00
    因为大模型运行一次推断只能推断出下一个字(实际上是 token )
    geelaw
        5
    geelaw  
       2023-10-13 01:11:08 +08:00 via iPhone
    @noe132 #2
    @airyland #3
    @jimages #4
    诸位似乎有点小看电脑的运行速度或者小看上下文切换和网络传输的延迟了。模型确实是一个一个预测的,但用户界面上几个字/词几个字/词显示回答纯粹是表演,API 里即使用 stream=True 也是一大段儿一大段儿收到回复的,否则反复多轮传输很不划算。
    noe132
        6
    noe132  
       2023-10-13 01:26:43 +08:00
    浏览器支持 SSE/WebSocket 长连接,每次只传输增量数据,没有多次传输的 overhead
    另外 API 的速度不是稳定的,可能有时候快有时候慢,很可能某个高峰期他就是 1 秒钟只吐一两个字。
    airyland
        7
    airyland  
       2023-10-13 01:40:29 +08:00
    @geelaw 没看明白你在说什么。
    如果你说提是 Azure OpenAI 一大段输出,那是因为它做了优化,进行合并输出,也可能是为了实现边输出边审查,OpenAI 更多是逐字逐词输出。
    geelaw
        8
    geelaw  
       2023-10-13 01:46:58 +08:00 via iPhone   ❤️ 5
    @airyland #7 我理解 OP 所问的是为什么网页上回答是几个词几个词往外蹦。

    1. 模型是一个 token 一个 token 输出的
    2. 用户在网页看到的是几个词几个词输出的
    3. 网页调用的 API 是一个词一个词返回数据到客户端的
    4. 网页调用 API 后增加动画让回答一个词一个词显示

    1 和 2 都成立,但 1 不是 2 的原因,4 才是 2 的原因,并且 3 不成立。这样说清楚了吗?

    关于 3 不成立,可以参考 https://stackoverflow.com/questions/75826303/is-there-any-way-to-stream-response-word-by-word-of-chatgpt-api-directly-in-reac 这个 StackOverflow 问题的存在就说明 OpenAI 的 API 并不是一个词一个词传送的。
    em70
        9
    em70  
       2023-10-13 02:34:40 +08:00
    你在说一句话之前,不可能知道你将要说的话的第三个词是啥,必须说完第二个词才知道.大模型是模仿人脑设计的
    MajestySolor
        10
    MajestySolor  
    OP
       2023-10-13 03:02:03 +08:00
    @em70
    这个模仿是纯粹的“模仿”还是说大语言模型的底层设计就是这样和人类说话一样的?
    人类说话在说到上一个字/词之前确实很难知道下一个字/词是啥,但这个特性需要模拟么,似乎并无益处啊,以计算机的算力完全可以生成完整内容以后再显示给用户,那么大语言模型模仿这个特性是不是纯粹是为了更像人。
    flyaway
        11
    flyaway  
       2023-10-13 03:11:39 +08:00
    @MajestySolor 人类的语言是线性的(读和写都是一个一个顺序进行的,不然人脑无法理解。)。 在 ML 领域,此类问题都称为 sequence modeling 问题,也是 NLP 中最常见的建模方式。
    ChatGPT 确实是一个一个 token 生成的,但是 OpenAI 可以:
    1. 每次 request 都等 ChatGPT 完成输出之后,一次性把一段话发给你
    2. 每次 request 都等 ChatGPT 完成输出之后,一个词一个词的发给你,模拟人的说话方式
    3. 每次 request 都是实时输出,但是模型很大,也许生成速度就是这样,不得不一个词一个词蹦。 虽然现在计算力很大,但是模型也很大啊……
    flyaway
        12
    flyaway  
       2023-10-13 03:14:46 +08:00
    BTW, 我觉得 8 楼说的是正解。
    eae29qvc
        13
    eae29qvc  
       2023-10-13 03:17:25 +08:00 via iPhone   ❤️ 1
    问过 azure 官方的人,纯粹是为了限流,充值足够完全可以秒回
    dnfQzjPBXtWmML
        14
    dnfQzjPBXtWmML  
       2023-10-13 04:27:18 +08:00
    @geelaw 要么你 f12 看看
    https://chat.openai.com/backend-api/conversation 这个 SSP 请求?下面这个请求,在我这耗时 16 秒,推了 407 个消息体,703,001 字节 headers:3,017; body:699,984 。而且可以看到,['message']['content']['parts'][0]每次推消息都在追加文本

    https://imgur.com/a/wxJ24Ix
    ziseyinzi
        15
    ziseyinzi  
       2023-10-13 05:26:16 +08:00
    类似于小米 8 透明探索版:后盖表面上是透明的,好像展示了内部结构,其实是一张贴纸照着内部结构画上去的。
    geelaw
        16
    geelaw  
       2023-10-13 06:46:21 +08:00
    @dnfQzjPBXtWmML #14 Good point. 我看了一下,并且调试了一下,如果在等待数据回传的时候下断点,等一会儿再让程序继续,则动画会直接跳到最终状态。因此我之前说“4 增加动画”是错误的,此外我查了文档

    https://github.com/openai/openai-cookbook/blob/main/examples/How_to_stream_completions.ipynb

    说明使用 stream 的时候每个 event 只传送一个 token ,但继续了解 Streams API

    https://developer.mozilla.org/en-US/docs/Web/API/Streams_API

    之后我意识到 event 的边界是 API-supplier-defined ,即应用层概念。于是我们可以问:

    > OpenAI 的 API 实现里,是每次得到新的 token 就立刻追加一个 event ,还是数个 tokens 一起组成数个 events 并发送?

    也就是代码是类似

    while (HasNextToken())
    {
    Respond(GetNextToken());
    }

    还是类似

    while (HasNextToken())
    {
    for (int i = 0; i <10 && HasNextToken(); ++i)
    {
    tokens[i] = GetNextToken();
    }
    Respond(tokens);
    }

    第一种情况,我认为 API 是在一个 token 一个 token 地返回数据,虽然传输层可以打包;第二种情况,我认为 API 一次传输了数个 tokens ,虽然传输层可以分成多个 packets 发送。

    但或许这个问题并不重要,token 生成、网络传输的延迟、客户端异步读取收到的数据,这些结合在一起自动导致了客户端动画。

    另外我对 message.content.parts[0] 每次都是到目前为止完整的文本而不是只发送变化的文本感到震惊,毕竟这会导致通信复杂度上升到 Theta(n^2)。
    swulling
        17
    swulling  
       2023-10-13 07:47:41 +08:00 via iPhone
    @eae29qvc 受限于单卡算力瓶颈,GPT-4 秒回是不可能的。

    其实这里有个计算公式,可以算出首 token 以及完全 token 的理论最快速度。
    makelove
        18
    makelove  
       2023-10-13 08:02:26 +08:00
    你在本地用 cpu 部署一个最快最次的 7b 小模型就知道了,目前的 ai 完全是暴力算法,我在老机上的 5 代 i3 就是一秒 2 token 水平。
    自然界进化这么多亿年的人类大脑就耗能极高速度极低,也许就是这种神经 ai 算法的本质复杂性,想出下一个词得扫一遍,永远都不可能快得起来。
    qwer1234zh
        19
    qwer1234zh  
       2023-10-13 08:22:10 +08:00 via Android
    看过 api 文档吧,有个 stream 开关,true 就是模仿打字机输出,false 就是结果完全输出
    naminokoe
        20
    naminokoe  
       2023-10-13 08:30:26 +08:00
    我使用 api 都是直接出现全部结果
    ospider
        21
    ospider  
       2023-10-13 08:37:25 +08:00   ❤️ 8
    没想到在 V 站上,这么简单的问题也能鸡同鸭讲,有人说原理,有人说具体实现,而且还互相打起来……

    从原理上来说,ChatGPT 用的模型是自回归的,也就是说,确确实实模型是需要一个字(token)一个字往外吐的。

    从实现上来说,可以等模型完全生成再返回给你,也就是上面有人提到的 `stream=False`。但是这样的用户体验反而不好,还不如把这个过程暴露给用户。但是考虑到网络传输,也不可能真的一个包只包含一个字符,那样传输的 overhead 和 latency 都太大了,所以你如果真的看返回的包的话,一个包里包含一段话。也就是说,其实传输上是完全缓存和完全 stream 的一个折中。

    再从商业上说,所谓充值可以一下返回,无非是优先级更高,返回更快,不可能改变模型自回归的根本属性……
    Seanfuck
        22
    Seanfuck  
       2023-10-13 08:48:24 +08:00
    生成确实是一个个字吐,传输的话,chatgpt 也是一个个字吐,百度则是一段段吐。
    估计跟带宽有关,老外网络好,一个个吐没影响(不会变慢也不在乎流量)。
    cheng6563
        23
    cheng6563  
       2023-10-13 09:26:46 +08:00
    因为语言模型就是输入一段聊天记录,模型生成回复中的下一个字。
    MEIerer
        24
    MEIerer  
       2023-10-13 09:26:58 +08:00
    因为爱情
    ztmqg
        25
    ztmqg  
       2023-10-13 09:27:48 +08:00
    Google Bard 是一次性返回
    swulling
        26
    swulling  
       2023-10-13 09:29:34 +08:00 via iPhone
    @Seanfuck 一段段是为了加内容过滤。按句过滤,这是因为上面要求必须先过滤后输出。
    obeyatonce
        27
    obeyatonce  
       2023-10-13 09:33:26 +08:00 via Android
    因为它并不像人类一样,是想好了一句话再说出来,而是根据模型计算后面要说的词是什么
    Takizawa
        28
    Takizawa  
       2023-10-13 09:44:18 +08:00
    难道没人用过 google Bard 吗?很明显 Bard 就不是一个字一个字地崩,而是直接给你结果,在给出结果之前有一个等待期。
    woooooOOOO
        29
    woooooOOOO  
       2023-10-13 10:15:56 +08:00
    transformer 模型就是一个字一个字的往外蹦,他们机器好速度应该是很快的,架不住用户多。
    我个人认为他们是给你分配一段时间来运行,一次出了很多字,一个一个给你,然后进程就切换了,轮到别人了,过一会再轮到你。
    一次性返回是等结果都出来再一次性返回。
    dnfQzjPBXtWmML
        30
    dnfQzjPBXtWmML  
       2023-10-13 11:54:33 +08:00
    @geelaw 还网络延迟呢😅
    dnfQzjPBXtWmML
        31
    dnfQzjPBXtWmML  
       2023-10-13 11:55:50 +08:00
    @Takizawa 很明显 bard 用的人不多,每个人分到了更多的算力
    geelaw
        32
    geelaw  
       2023-10-13 12:37:13 +08:00
    @dnfQzjPBXtWmML #30 这很奇怪吗?如果服务器快速产生事件,延迟很小但带宽也很小,那么客户端每次网络 IO 只能看到一部份事件;如果服务器慢速产生事件,延迟很大且带宽很大,那么客户端第一次网络 IO 很可能会看到累积的好多事件。每次 IO 之后操作了 DOM ,并且下次进入 IO 等待的时候浏览器会渲染,因此会看到动画效果。
    locoz
        33
    locoz  
       2023-10-13 12:41:58 +08:00 via Android
    @geelaw #5 主要还是可用算力资源的问题,公共免费服务的资源有限,如果不出一个词就输出一次显示会导致感受上等待了很久,用户体验差;而付费 API 可用资源多,可以在短时间内连续输出多个词,所以完全可以做到攒一批再发送,实现看起来的一次一大段回复甚至短暂等待后直接得到完整回复。
    maxxfire
        34
    maxxfire  
       2023-10-13 12:47:26 +08:00   ❤️ 1
    很多印度人在后面敲,显然人手不足,所以回复的比较慢
    tsja
        35
    tsja  
       2023-10-13 13:08:38 +08:00
    @airyland 这个网站好棒
    eae29qvc
        36
    eae29qvc  
       2023-10-13 15:03:45 +08:00 via iPhone
    @swulling 意思就是从你提交请求到客户端收到第一个字前,结果已经出来了,当然出结果需要一定时间,一个字一个字返回就是为了限流,充钱多优先级就高,秒回的意思是只要结果出了就直接全部返回,这是 azure 技术人员说的
    moonbeama
        37
    moonbeama  
       2023-10-13 15:16:26 +08:00
    流式响应,可以看看 uni-ai 的官网的文档,之前接入玩过,目的就是减少响应时间吧(虽然并没有),但至少用户在界面上不会什么都看不到
    dnfQzjPBXtWmML
        38
    dnfQzjPBXtWmML  
       2023-10-13 16:09:09 +08:00
    @geelaw “但或许这个问题并不重要,token 生成、网络传输的延迟、客户端异步读取收到的数据,这些结合在一起自动导致了客户端动画。”:每次对话几十秒,token 生成占多少时间,网络延迟占多少时间?我不认为这个场景下所谓“通信复杂度上升到 Theta(n^2)”是什么值得真正工作过的程序员震惊甚至关注到的东西。
    swulling
        39
    swulling  
       2023-10-13 16:26:43 +08:00 via iPhone
    @eae29qvc 那你就是听错了或者对方不专业。
    geelaw
        40
    geelaw  
       2023-10-13 17:09:15 +08:00 via iPhone
    @dnfQzjPBXtWmML #38 不是很确定你的数据来自什么环境,同款和类似的对话我这边是几秒钟。我比较好奇你认为每个数值分别应该是多少。

    此外,你似乎没有理解我的意思,我是说 OpenAI 的 API 到底是类似第一种还是第二种实现(只要一次累积的 tokens 数量没有太大),最终网页上显示的效果没有区别。

    考虑 2000 tokens 且每 token 有 4 个字符的情况,若每次传输到目前为止的总文本,最终会传送至少 7.6 MB ;若每次只传输增量,这一数值可以降低到 7.8 KB 。我只能说希望现在的软件工程师不要把性能进步都吃掉,恢复一点上个世纪的人的美好品质。
    PrinceofInj
        41
    PrinceofInj  
       2023-10-13 17:41:33 +08:00
    @em70 人脑可不是这样。我在打算回复这段话的瞬间已经想好整句话怎么说了,只不过受限于我的打字速度才一个字一个字打出来的。人脑某种意义上是类似于量子计算的。
    eae29qvc
        42
    eae29qvc  
       2023-10-13 17:56:32 +08:00 via iPhone
    @swulling 大语言模型是一个字一个字输出的,但是 azure 那边确实是等全部内容输出后再返回给用户的,因为还要做 content filter ,content filter 是用别的模型做的
    eae29qvc
        43
    eae29qvc  
       2023-10-13 18:03:32 +08:00 via iPhone
    @swulling 人家专门上门过来卖服务的,掏多少钱给多快响应速度,甚至 content filter 都可以定制,而且 azure 的 gpt 也不会跑在单卡上吧
    iOCZ
        44
    iOCZ  
       2023-10-13 18:57:08 +08:00
    也许你不太相信,但是它的确是一个 token ,一个 token 生成的。。。当然你也可以攒起来再发给前端
    swulling
        45
    swulling  
       2023-10-13 19:50:03 +08:00
    @eae29qvc

    > 掏多少钱给多快响应速度

    我说了,这个是不可能的,有瓶颈。
    另外单卡推理比多卡、多机推理快,这是因为传输瓶颈。
    swulling
        46
    swulling  
       2023-10-13 19:57:37 +08:00
    @eae29qvc #42

    > azure 那边确实是等全部内容输出后再返回给用户的

    并不是全部内容,如果开了流式,是分句。国内的大模型比如文心一言也是分句,按句进行内容过滤。
    jptx
        47
    jptx  
       2023-10-13 20:32:30 +08:00
    @airyland #3 感谢推荐网站,被这个前端惊艳到了
    dnfQzjPBXtWmML
        48
    dnfQzjPBXtWmML  
       2023-10-13 20:50:49 +08:00
    @geelaw 生成 token 比推送到客户端并显示开销高得多,所以所有的设计都主要被 LLM 本身的特性所限制。你重现对话速度快可能和当时的使用人数有关,北京时间深夜用比白天速度慢。另外,如果工程师们如果有更重要的事情做,那么不浪费时间在优化细节上面没什么问题。
    em70
        49
    em70  
       2023-10-13 23:34:23 +08:00   ❤️ 1
    @PrinceofInj #41 我不信,你最多想好了一个观点,具体怎么表达一定是边说边想的。人脑的内存不可能放下一整句话,6 位验证码已经极限了,要是 8 位就会需要看两次才能输对
    PrinceofInj
        50
    PrinceofInj  
       2023-10-13 23:44:13 +08:00
    @em70 所以我说类似于量子退火的过程。在输出的时候才具象化,但是在输出前,实际上已经定好了。最明显的例子,我们在回想一件事的时候,是瞬间想到这件事儿的整体的,而不是说类似计算机 select from where 等到命中目标后再从大脑记忆中逐渐读取。
    mmdsun
        51
    mmdsun  
       2023-10-14 11:32:06 +08:00 via iPhone
    @airyland
    @eae29qvc
    @swulling
    我的 Azure 是一个个字输出的,不是整句话和 OpenAi 一样流畅,可能后面有改动。
    mmdsun
        52
    mmdsun  
       2023-10-14 11:34:29 +08:00 via iPhone
    模型是这样的,可以理解为成语接龙。

    如果实现的话 js 前端和后端 Java 参考:
    https://stackoverflow.com/questions/76334679/how-get-response-in-axios-when-api-is-steam-like-sse-server-send-events
    locoz
        53
    locoz  
       2023-10-14 23:20:27 +08:00
    @PrinceofInj #43 其实是你对比的对象错了,人脑思考出一整句话的过程应该等同于语言模型一个一个词往外输出的过程,而不是你打字输出的过程,后者实际等同于得到了语言模型的完整输出结果后,再表演性质地来一遍打字效果。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2870 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 13:59 · PVG 21:59 · LAX 05:59 · JFK 08:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.