精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

ChatGPT是如何做到一個字一個字輸出的?

開發 后端 人工智能
大語言模型生成響應整個結果的過程是比較漫長的,但逐token生成的響應比較快,ChatGPT將這一特性與SSE技術充分結合,一個字一個字地彈出回復,在用戶體驗上實現了質的提升。

ChatGPT回答問題時,是一個字一個字彈出的,給人一種在認真思考的感覺。

這段對話的基本內容是:

問:大語言生成式模型是如何工作的
答:大型語言生成模型(如GPT-3)是基于深度學習技術的神經網絡模型。這些模型通常使用一種稱為"Transformer"的架構,該架構在自然語言處理領域取得了巨大的成功。

下面是大型語言生成模型的工作原理概述:

... 省略一段 ...

生成文本:一旦模型經過訓練,就可以使用它來生成文本。給定一個初始文本或提示,模型會根據已經學到的概率分布生成下一個單詞,然后使用生成的單詞作為輸入,并繼續生成下一個單詞,以此類推,直到達到所需的文本長度或生成終止符號。

... 省略一段 ...

大語言模型,Large Language Model,簡稱LLM。

從模型的視角來看,LLM每進行一次推理生成一個token,直到達到文本長度限制或生成終止符。

從服務端的視角來看,生成的token需要通過HTTPS協議逐個返回到瀏覽器端。

Client-Server 模式下,常規的交互方式是client端發送一次請求,接收一次響應。顯然,這無法滿足ChatGPT回復問題的場景。

其次,我們可能想到websocket,它依賴HTTP實現握手,升級成WebSocket。不過WebSocket需要client和server都持續占用一個socket,server側成本比較高。

ChatGPT使用的是一種折衷方案: server-sent event(簡稱SSE). 我們從OpenAI的 API 文檔可以發現這一點:

SSE 模式下,client只需要向server發送一次請求,server就能持續輸出,直到需要結束。整個交互過程如下圖所示:

SSE仍然使用HTTP作為應用層傳輸協議,充分利用HTTP的長連接能力,實現服務端推送能力。

從代碼層面來看,SSE模式與單次HTTP請求不同的點有:

  1. client端需要開啟 keep-alive,保證連接不會超時。
  2. HTTP響應的Header包含 Content-Type=text/event-stream,Cache-Cnotallow=no-cache 等。
  3. HTTP響應的body一般是 "data: ..." 這樣的結構。
  4. HTTP響應里可能有一些空數據,以避免連接超時。

以 ChatGPT API 為例,在發送請求時,將stream參數設置為true就啟用了SSE特性,但在讀取數據的SDK里需要稍加注意。

在常規模式下,拿到 http.Response 后,用 ioutil.ReadAll 將數據讀出來即可,代碼如下:

func main() {
  payload := strings.NewReader(`{
    "model": "gpt-3.5-turbo",
    "messages": [{"role": "user", "content": "大語言生成式模型是如何工作的"}],
    "max_tokens": 1024,
    "temperature": 1,
    "top_p": 1,
    "n": 1,
    "stream": false
}`)

  client := &http.Client{}
  req, _ := http.NewRequest("POST", "https://api.openai.com/v1/chat/completions", payload)
  req.Header.Add("Content-Type", "application/json")
  req.Header.Add("Authorization", "Bearer <OpenAI-Token>")

  resp, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer resp.Body.Close()

  body, _ := ioutil.ReadAll(resp.Body)
  fmt.Println(string(body))
}

執行大概耗費20s+,得到一個完整的結果:

{
  "id": "chatcmpl-7KklTf9mag5tyBXLEqM3PWQn4jlfD",
  "object": "chat.completion",
  "created": 1685180679,
  "model": "gpt-3.5-turbo-0301",
  "usage": {
    "prompt_tokens": 21,
    "completion_tokens": 358,
    "total_tokens": 379
  },
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "大語言生成式模型通常采用神經網絡來實現,具體工作流程如下:\n\n1. 數據預處理:將語料庫中的文本數據進行預處理,包括分詞、刪除停用詞(如“的”、“了”等常用詞匯)、去重等操作,以減少冗余信息。\n\n2. 模型訓練:采用遞歸神經網絡(RNN)、長短期記憶網絡(LSTM)或變種的Transformers等模型進行訓練,這些模型都具有一定的記憶能力,可以學習到語言的一定規律,并預測下一個可能出現的詞語。\n\n3. 模型應用:當模型完成訓練后,可以將其應用于實際的生成任務中。模型接收一個輸入文本串,并預測下一個可能出現的詞語,直到達到一定長度或遇到結束符號為止。\n\n4. 根據生成結果對模型進行調優:生成的結果需要進行評估,如計算生成文本與語料庫文本的相似度、流暢度等指標,以此來調優模型,提高其生成質量。\n\n總體而言,大語言生成式模型通過對語言的規律學習,從而生成高質量的文本。"
      },
      "finish_reason": "stop",
      "index": 0
    }
  ]
}

如果我們將 stream 設置為 true,不做任何修改,請求總消耗28s+,體現為很多條 stream 消息:

上面這張圖是一張Postman調用 chatgpt api的圖,走的就是 ioutil.ReadAll 的模式。為了實現stream讀取,我們可以分段讀取 http.Response.Body。下面是這種方式可行的原因:

  1. http.Response.Body 的類型是 io.ReaderCloser,底層依賴一個HTTP連接,支持stream讀。
  2. SSE 返回的數據通過換行符\n進行分割

所以修正的方法是通過bufio.NewReader(resp.Body)包裝起來,并在一個for-loop里讀取, 代碼如下:

// stream event 結構體定義
type ChatCompletionRspChoiceItem struct {
  Delta        map[string]string `json:"delta,omitempty"` // 只有 content 字段
  Index        int               `json:"index,omitempty"`
  Logprobs     *int              `json:"logprobs,omitempty"`
  FinishReason string            `json:"finish_reason,omitempty"`
}

type ChatCompletionRsp struct {
  ID      string                        `json:"id"`
  Object  string                        `json:"object"`
  Created int                           `json:"created"` // unix second
  Model   string                        `json:"model"`
  Choices []ChatCompletionRspChoiceItem `json:"choices"`
}

func main() {
  payload := strings.NewReader(`{
    "model": "gpt-3.5-turbo",
    "messages": [{"role": "user", "content": "大語言生成式模型是如何工作的"}],
    "max_tokens": 1024,
    "temperature": 1,
    "top_p": 1,
    "n": 1,
    "stream": true
}`)

  client := &http.Client{}
  req, _ := http.NewRequest("POST", "https://api.openai.com/v1/chat/completions", payload)
  req.Header.Add("Content-Type", "application/json")
  req.Header.Add("Authorization", "Bearer "+apiKey)
  req.Header.Set("Accept", "text/event-stream")
  req.Header.Set("Cache-Control", "no-cache")
  req.Header.Set("Connection", "keep-alive")

  resp, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer resp.Body.Close()

  reader := bufio.NewReader(resp.Body)
  for {
    line, err := reader.ReadBytes('\n')
    if err != nil {
      if err == io.EOF {
        // 忽略 EOF 錯誤
        break
      } else {
        if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
          fmt.Printf("[PostStream] fails to read response body, timeout\n")
        } else {
          fmt.Printf("[PostStream] fails to read response body, err=%s\n", err)
        }
      }
      break
    }
    line = bytes.TrimSuffix(line, []byte{'\n'})
    line = bytes.TrimPrefix(line, []byte("data: "))
    if bytes.Equal(line, []byte("[DONE]")) {
      break
    } else if len(line) > 0 {
      var chatCompletionRsp ChatCompletionRsp
      if err := json.Unmarshal(line, &chatCompletionRsp); err == nil {
        fmt.Printf(chatCompletionRsp.Choices[0].Delta["content"])
      } else {
        fmt.Printf("\ninvalid line=%s\n", line)
      }
    }
  }

  fmt.Println("the end")
}

看完client端,我們再看server端。現在我們嘗試mock chatgpt server逐字返回一段文字。這里涉及到兩個點:

  1. Response Header 需要設置 Connection 為 keep-alive 和 Content-Type 為 text/event-stream。
  2. 寫入 respnose 以后,需要flush到client端。

代碼如下:

func streamHandler(w http.ResponseWriter, req *http.Request) {
  w.Header().Set("Connection", "keep-alive")
  w.Header().Set("Content-Type", "text/event-stream")
  w.Header().Set("Cache-Control", "no-cache")

  var chatCompletionRsp ChatCompletionRsp
  runes := []rune(`大語言生成式模型通常使用深度學習技術,例如循環神經網絡(RNN)或變壓器(Transformer)來建模語言的概率分布。這些模型接收前面的詞匯序列,并利用其內部神經網絡結構預測下一個詞匯的概率分布。然后,模型將概率最高的詞匯作為生成的下一個詞匯,并遞歸地生成一個詞匯序列,直到到達最大長度或遇到一個終止符號。

在訓練過程中,模型通過最大化生成的文本樣本的概率分布來學習有效的參數。為了避免模型產生過于平凡的、重復的、無意義的語言,我們通常會引入一些技巧,如dropout、序列擾動等。
  
大語言生成模型的重要應用包括文本生成、問答系統、機器翻譯、對話建模、摘要生成、文本分類等。`)
  for _, r := range runes {
    chatCompletionRsp.Choices = []ChatCompletionRspChoiceItem{
      {Delta: map[string]string{"content": string(r)}},
    }

    bs, _ := json.Marshal(chatCompletionRsp)
    line := fmt.Sprintf("data: %s\n", bs)
    fmt.Fprintf(w, line)
    if f, ok := w.(http.Flusher); ok {
      f.Flush()
    }

    time.Sleep(time.Millisecond * 100)
  }

  fmt.Fprintf(w, "data: [DONE]\n")
}

func main() {
  http.HandleFunc("/stream", streamHandler)
  http.ListenAndServe(":8088", nil)
}

在真實場景中,要返回的數據來源于另一個服務或函數調用,如果這個服務或函數調用返回時間不穩定,可能導致client端長時間收不到消息,所以一般的處理方式是:

  1. 對第三方的調用放到一個 goroutine 中。
  2. 通過 time.Tick 創建一個定時器,向client端發送空消息。
  3. 創建一個timeout channel,避免響應時間太久。

為了能夠從不同的channel讀取數據,select 是一個不錯的關鍵字,比如這段演示代碼:

// 聲明一個 event channel
// 聲明一個 time.Tick channel
// 聲明一個 timeout channel

select {
case ev := <-events:
  // send data event
case <- timeTick:
  // send empty event
case <-timeout:
    fmt.Fprintf(w, "[Done]\n\n")
}

小結一下

大語言模型生成響應整個結果的過程是比較漫長的,但逐token生成的響應比較快,ChatGPT將這一特性與SSE技術充分結合,一個字一個字地彈出回復,在用戶體驗上實現了質的提升。

縱觀生成式模型,不管是LLAMA/小羊駝 (不能商用),還是Stable Diffusion/Midjourney。在提供線上服務時,均可利用SSE技術節省提升用戶體驗,節省服務器資源。

責任編輯:姜華 來源: 今日頭條
相關推薦

2022-06-28 11:30:38

廣電5G套餐專網

2013-05-21 17:42:39

打車AppO2O

2023-04-25 15:46:51

Python字符串

2020-09-18 14:23:50

字符

2022-10-28 09:10:40

數據結構字典樹

2022-11-24 08:01:57

bash腳本字符串

2025-01-21 08:30:00

2021-07-26 10:58:07

Chromebook谷歌更新

2021-04-14 07:47:59

Read磁盤IO

2020-11-11 17:53:50

腦機接口機器人工智能

2022-06-14 09:14:39

漏洞惡意依賴木馬

2010-09-16 10:56:46

sqlserver建表

2010-10-09 13:41:42

MySQL字符串

2019-12-16 09:26:05

Java設計操作系統

2013-07-29 04:31:25

iOS開發iOS開發學習整個App設置一個字體

2012-05-09 16:12:07

筆記本評測

2023-03-16 10:24:21

列表元素字典

2020-06-28 14:18:23

Python代碼開發

2012-12-17 12:58:18

WebjQuery重構

2017-06-30 15:18:24

對賬系統互聯網
點贊
收藏

51CTO技術棧公眾號

天堂av一区二区| 久久天天躁狠狠躁夜夜av| 日韩欧美国产免费| 韩日在线视频| 久99久精品视频免费观看| 久久电影一区二区| 亚洲国产精品无码久久久久高潮| 中文字幕在线免费观看视频| 国产蜜臀97一区二区三区 | 欧美人与禽性xxxxx杂性| 成人激情小说网站| 国产精品福利无圣光在线一区| 任我爽在线视频| 国产精品主播在线观看| 欧美午夜精品一区| 久操手机在线视频| 国产精品秘入口| 国产激情一区二区三区| 日本精品视频在线播放| 卡通动漫亚洲综合| 自拍亚洲一区| 日韩欧美电影一区| 另类小说第一页| 激情av在线播放| 国产欧美视频在线观看| 国产日韩欧美一区二区三区四区| 最新国产中文字幕| 亚洲人成在线影院| 久久激情视频久久| 国产精品国产三级国产专业不| 亚洲啊v在线免费视频| 欧洲国内综合视频| 少妇高潮毛片色欲ava片| 女女色综合影院| 久久久www成人免费毛片麻豆| av一区二区三区免费| 国产精品第6页| 国产视频一区免费看| 久久亚洲精品一区| 99国产精品免费| 欧美一级一片| 精品国产伦一区二区三区观看方式| 香蕉视频禁止18| 国产v综合v| 狠狠色狠色综合曰曰| 妞干网在线播放| www免费视频观看在线| 欧美国产日韩a欧美在线观看| 久久综合久久久| 少妇精品视频一区二区 | xxxx视频在线观看| va天堂va亚洲va影视| 欧美图片一区二区三区| 日本老熟妇毛茸茸| 欧美7777| 日本精品一区二区三区四区的功能| 波多野结衣之无限发射| 电影在线观看一区| 亚洲成人午夜电影| 国产一二三在线视频| 福利在线导航136| 亚洲成av人影院在线观看网| 免费超爽大片黄| 丁香花在线影院| 亚洲成人在线网站| 欧美网站免费观看| 另类图片综合电影| 91福利资源站| 婷婷六月天在线| 亚洲精品大片| 日韩一区二区三| 韩国三级视频在线观看| 国产成人在线中文字幕| 欧美精品一区二区三区很污很色的 | 久久aⅴ国产紧身牛仔裤| 45www国产精品网站| 欧美日韩乱国产| 久久精品国语| 国产精品日韩专区| 国产精品久久久久久久久久久久久久久久久久 | 久久久久久在线观看| 久久久久国产精品一区二区| 国产精品久久色| 国产女人18毛片水18精| 成人午夜碰碰视频| 欧美男人的天堂| 天堂资源在线中文| 亚洲国产一区二区视频| 91猫先生在线| 欧美美女福利视频| 日韩欧美国产综合一区 | 高清欧美性猛交xxxx黑人猛| 亚洲精品久久久久中文字幕欢迎你| 色欲av无码一区二区三区| 三上亚洲一区二区| 久久久人成影片一区二区三区| 亚洲黄色激情视频| 激情综合色丁香一区二区| 午夜成人免费视频| 精品不卡在线| 亚洲一卡二卡在线观看| 在线播放日韩| 国产精品久久久久免费a∨| 国产又粗又大又爽| 97久久精品人人澡人人爽| 久久午夜羞羞影院免费观看| 91精品久久久久久久久| www.国产欧美| 久久亚洲影视婷婷| 国产精品久久久久一区二区| 青青国产在线观看| 免费的成人av| 国产精品免费在线播放| av午夜在线| 亚洲国产欧美一区二区三区丁香婷| 成年人免费大片| av手机免费在线观看| 一本一本久久a久久精品综合麻豆| 午夜午夜精品一区二区三区文| 精品精品导航| 欧美人体做爰大胆视频| 久久久久亚洲无码| 9999国产精品| 日韩美女在线播放| 国 产 黄 色 大 片| 国产激情一区二区三区| 成人黄动漫网站免费| av网站在线免费观看| 色综合中文字幕| 久久久性生活视频| 国产一区二区高清在线| 亚洲午夜未满十八勿入免费观看全集| 久久精品日韩无码| 99在线精品视频在线观看| 国产三级一区二区三区| 日韩免费观看网站| 中文字幕视频免费观看| 99久久伊人精品| 国产在线播放一区二区| 91麻豆一二三四在线| 欧美日韩一区二区三区四区| 爱爱免费小视频| 99视频精品| 国外成人在线视频网站| 先锋成人av| 欧美一级日韩不卡播放免费| av最新在线观看| 久久电影国产免费久久电影| 亚洲日本精品国产第一区| 主播大秀视频在线观看一区二区| 亚洲激情在线观看| 日本在线小视频| 成人av在线一区二区三区| 欧美午夜性视频| 国产精品一线| 欧美在线中文字幕| 嫩草精品影院| 在线观看日韩国产| 91精品人妻一区二区三区| 视频在线在亚洲| 五月天色一区| 亚洲男人在线| 欧美第一淫aaasss性| 精品人妻无码一区二区三区蜜桃一| 亚洲天堂久久久久久久| 宇都宫紫苑在线播放| 中文字幕一区二区三区欧美日韩| 亚洲iv一区二区三区| 18av在线视频| 精品伦理精品一区| 国产午夜久久久| 91丨九色丨蝌蚪富婆spa| 国产成人精品视频免费看| 国产成人调教视频在线观看| 国产精品福利观看| 国产美女在线观看| 精品欧美一区二区在线观看| 四虎永久在线精品| 久久久精品人体av艺术| 污版视频在线观看| 欧美在线黄色| 久久精品日产第一区二区三区精品版 | 狠狠网亚洲精品| 成年人看的毛片| 国产欧美日韩在线一区二区 | 少妇高潮毛片色欲ava片| 亚洲日产av中文字幕| 国产精品亚洲欧美导航| 青春草免费在线视频| 亚洲精品一区二区在线| 亚洲综合网av| 欧美国产精品久久| 国产成人亚洲精品无码h在线| 欧美黑人巨大videos精品| 日韩av免费在线观看| 日本亚洲精品| 亚洲激情在线观看| 在线观看中文字幕码| 亚洲成a人片在线观看中文| 亚洲а∨天堂久久精品2021| 国产精品99久久久| 久久精品香蕉视频| 欧美午夜不卡| 亚洲激情一区二区| 高清日韩欧美| 国产欧美精品日韩精品| 嗯啊主人调教在线播放视频| 国产精品人成在线观看免费| 国产成人一区二区三区电影| 色影院视频在线| 亚洲成人黄色在线| 一本一道人人妻人人妻αv| 亚洲成人午夜影院| 久草福利资源在线| 久久久久国产一区二区三区四区| 国模大尺度视频| 日韩国产精品久久久久久亚洲| 成人免费a级片| 欧洲激情综合| 久中文字幕一区| 91九色鹿精品国产综合久久香蕉| 国产精品嫩草视频| 欧美久久天堂| 欧美黑人性视频| 免费黄色在线| 在线视频欧美日韩| 天堂在线免费av| 欧美r级电影在线观看| 一本到在线视频| 91官网在线观看| 中文在线第一页| 天天做天天摸天天爽国产一区| av激情在线观看| 中文字幕一区二区三区在线不卡| 亚洲黄色小说视频| 99国产精品久久久久久久久久| 苍井空张开腿实干12次| 国产伦精品一区二区三区视频青涩| 天天爱天天操天天干| 日韩精品91亚洲二区在线观看| 亚洲午夜无码av毛片久久| 在线观看的日韩av| www.好吊操| 亚洲视频综合| 精品无码国产一区二区三区av| 欧美三区视频| 国产xxxx振车| 影音先锋在线一区| 黄页网站大全在线观看| 激情一区二区| 久久久久久久久久网| 亚洲青色在线| 99视频在线免费播放| 亚洲三级国产| av网站在线观看不卡| 亚洲作爱视频| 久久久免费视频网站| 午夜综合激情| 99视频在线免费| 久久国产生活片100| 亚洲免费成人在线视频| 国产一区欧美一区| 日本久久久久久久久久| av影院午夜一区| 久久av无码精品人妻系列试探| 久久久777精品电影网影网 | 欧美一级做a| 成人黄色影片在线| 午夜日韩影院| 久久一区二区精品| 欧美手机在线| 亚洲免费视频播放| 伊人久久久大香线蕉综合直播| 六月丁香婷婷激情| 蜜桃久久av一区| 日本亚洲一区二区三区| 99综合电影在线视频| 亚洲国产天堂av| 最新不卡av在线| 久久久精品一区二区涩爱| 精品久久久久久久大神国产| 中日韩在线观看视频| 日韩一区二区三区av| 亚洲av毛片成人精品| 一区二区三区国产在线观看| 成人直播在线| 欧美孕妇毛茸茸xxxx| 国产成人亚洲一区二区三区| 成人在线看片| 国产中文字幕一区二区三区| 性做爰过程免费播放| 免费日韩av片| 爱情岛论坛亚洲自拍| 久久先锋影音av鲁色资源| 日韩a级片在线观看| 欧美日韩在线视频一区| 一区二区三区精彩视频| 亚洲国产免费av| 欧美日本一道| 欧美亚洲激情视频| 国产精品18| 欧美性天天影院| 国产一区观看| 999精彩视频| 99re成人在线| 一级黄色录像视频| 欧美在线观看一区| 成人毛片视频免费看| 最近2019年中文视频免费在线观看 | 神马久久久久久久 | 国产99久久久欧美黑人| 欧美h版在线观看| 性刺激综合网| 国产一区二区你懂的| 69久久精品无码一区二区| 久久精品这里都是精品| 国产污片在线观看| 91精品久久久久久久91蜜桃| 麻豆导航在线观看| 韩日欧美一区二区| 欧洲精品99毛片免费高清观看| 日韩av免费电影| 亚洲尤物影院| 一级黄色电影片| 亚洲欧美另类图片小说| 中文字幕日本视频| 亚洲精品一区久久久久久| bl视频在线免费观看| 91久久精品一区二区别| 999久久久91| 国产精品视频分类| 国产女同性恋一区二区| 99精品在线播放| 日韩成人在线电影网| 国产黄色大片在线观看| 超碰97国产在线| 欧美在线国产| 国产成人av片| 一区二区国产视频| va视频在线观看| 久久久久999| 国产精品麻豆| 日韩最新中文字幕| 精品一区二区三区久久| 亚洲一二三四五六区| 欧美日韩国产中文| 日本电影在线观看网站| 国产精品久久av| 欧美日韩激情在线一区二区三区| 日本新janpanese乱熟| 亚洲国产精品ⅴa在线观看| 成人h动漫精品一区二区下载| 亚洲日本成人网| 欧美暴力调教| 这里只有精品66| 国产一区二区三区蝌蚪| 国产精品成人免费观看| 精品三级在线看| 日韩av影片| 奇米影视首页 狠狠色丁香婷婷久久综合 | 日韩中文字幕久久| 精品一区二区三区亚洲| 久久免费一级片| 成人蜜臀av电影| 91在线视频在线观看| 揄拍成人国产精品视频| 伊人久久大香| 日本wwwcom| 91片在线免费观看| 中文字幕乱码一区二区| 超薄丝袜一区二区| 国产精品中文字幕制服诱惑| 日韩手机在线观看视频| 中文字幕亚洲视频| www.av黄色| 欧美一级片久久久久久久| 成人看的羞羞网站| 中文字幕无码毛片免费看| 精品久久久久久久久中文字幕| 国产三级在线免费| 亚洲一区二区三区视频| 亚洲日本成人| 免费黄色在线网址| 日韩精品一区二区在线观看| 亚洲欧洲自拍| 天天成人综合网| 99视频超级精品| 亚洲综合精品在线| 91精品国产乱码久久久久久蜜臀 | 国产亚洲精品成人av久久ww| 只有精品亚洲| jizzjizz国产精品喷水| 国产精品欧美精品| 六月婷婷中文字幕| 国产精品视频男人的天堂| 国产精品久久| 男女男精品视频网站| 亚洲第一精品夜夜躁人人爽| 国产精品xxx| 大陆极品少妇内射aaaaa|