Rumah  >  Artikel  >  Peranti teknologi  >  Bagaimanakah ChatGPT mengeluarkan perkataan demi perkataan?

Bagaimanakah ChatGPT mengeluarkan perkataan demi perkataan?

WBOY
WBOYke hadapan
2023-06-02 17:40:222055semak imbas

Bagaimanakah ChatGPT mengeluarkan perkataan demi perkataan?

Apabila ChatGPT menjawab soalan, ia muncul perkataan demi perkataan, memberikan orang perasaan bahawa mereka sedang berfikir secara serius.

Kandungan asas perbualan ini ialah:

S: Bagaimanakah model generatif bahasa besar berfungsi
Jawapan: Model penjanaan bahasa berskala besar (seperti GPT-3) ialah model rangkaian saraf berdasarkan teknologi pembelajaran mendalam. Model-model ini sering menggunakan seni bina yang dipanggil "Transformer", yang telah mencapai kejayaan besar dalam bidang pemprosesan bahasa semula jadi.

Berikut ialah gambaran keseluruhan cara model penjanaan bahasa besar berfungsi:

. .. Tinggalkan perenggan...

Jana teks: Setelah model dilatih, ia boleh digunakan untuk menjana teks. Memandangkan teks atau gesaan awal, model menjana perkataan seterusnya berdasarkan taburan kebarangkalian yang telah dipelajari, kemudian menggunakan perkataan yang dijana sebagai input dan terus menjana perkataan seterusnya, dan seterusnya sehingga panjang teks yang diingini dicapai atau dijana Penamatan simbol.

... Tinggalkan perenggan...

Model Bahasa Besar, Besar Model Bahasa, dirujuk sebagai LLM.

Dari perspektif model, LLM menjana token setiap kali ia melakukan inferens sehingga had panjang teks dicapai atau penamat dijana.

Dari perspektif pelayan, token yang dijana perlu dikembalikan kepada penyemak imbas satu demi satu melalui protokol HTTPS.

Dalam mod Pelayan-Pelanggan, kaedah interaksi konvensional ialah pelanggan menghantar permintaan dan menerima respons. Jelas sekali, ini tidak dapat memenuhi senario ChatGPT membalas soalan.

Kedua, kita mungkin memikirkan websocket, yang bergantung pada HTTP untuk melaksanakan jabat tangan dan dinaik taraf kepada WebSocket. Walau bagaimanapun, WebSocket memerlukan kedua-dua pelanggan dan pelayan untuk terus menduduki soket, dan kos di bahagian pelayan agak tinggi.

CtGPT menggunakan kompromi: acara yang dihantar oleh pelayan (pendek kata SSE kami boleh menemui ini daripada dokumentasi API OpenAI:

Bagaimanakah ChatGPT mengeluarkan perkataan demi perkataan?

Dalam mod SSE, pelanggan hanya perlu menghantar permintaan kepada pelayan sekali sahaja, dan pelayan boleh meneruskan output sehingga penghujung diperlukan. Keseluruhan proses interaksi ditunjukkan dalam rajah di bawah:

Bagaimanakah ChatGPT mengeluarkan perkataan demi perkataan?

SSE masih menggunakan HTTP sebagai protokol penghantaran lapisan aplikasi, menggunakan sepenuhnya sambungan HTTP yang panjang keupayaan untuk melaksanakan keupayaan Push sebelah pelayan.

Dari peringkat kod, perbezaan antara mod SSE dan satu permintaan HTTP ialah:

  1. Keep perlu dihidupkan di sisi klien -alive memastikan sambungan tidak akan tamat masa.
  2. Pengepala respons HTTP mengandungi Content-Type=text/event-stream, Cache-Cnotallow=no-cache, dsb.
  3. Ibu tindak balas HTTP secara amnya ialah struktur seperti "data: ...".
  4. Respon HTTP mungkin mengandungi beberapa data kosong untuk mengelakkan tamat masa sambungan.

Ambil API ChatGPT sebagai contoh Apabila menghantar permintaan, menetapkan parameter strim kepada benar membolehkan ciri SSE, tetapi anda perlu memberi sedikit perhatian dalam SDK yang. membaca data.

Dalam mod biasa, selepas mendapat http.Response, gunakan ioutil.ReadAll untuk membaca data berikut:

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))}</openai-token>

mengambil masa kira-kira 20s+ untuk dilaksanakan dan mendapat hasil yang lengkap:

{"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}]}

Jika kami menetapkan strim kepada benar tanpa membuat sebarang pengubahsuaian, jumlah permintaan menggunakan 28s+, yang mana mencerminkan Untuk banyak mesej strim:

Bagaimanakah ChatGPT mengeluarkan perkataan demi perkataan?

Gambar di atas ialah gambar Posmen yang memanggil api chatgpt, menggunakan mod ioutil.ReadAll. Untuk melaksanakan pembacaan aliran, kita boleh membaca http.Response.Body dalam segmen. Inilah sebabnya mengapa ini berfungsi:

  1. http.Response.Body adalah jenis io.ReaderCloser , lapisan bawah bergantung pada sambungan HTTP dan menyokong pembacaan strim.
  2. Data yang dikembalikan oleh SSE dipecahkan oleh aksara baris baharu n

Jadi kaedah pembetulan adalah untuk lulus bufio .NewReader(resp.Body)Balut dan baca dalam gelung untuk Kod adalah seperti berikut:

// stream event 结构体定义type ChatCompletionRspChoiceItem struct {Deltamap[string]string `json:"delta,omitempty"` // 只有 content 字段Indexint `json:"index,omitempty"`Logprobs *int`json:"logprobs,omitempty"`FinishReason string`json:"finish_reason,omitempty"`}type ChatCompletionRsp struct {IDstring`json:"id"`Objectstring`json:"object"`Created int `json:"created"` // unix secondModel 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 ChatCompletionRspif 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")}

Selepas membaca bahagian klien, mari kita lihat bahagian pelayan. Sekarang kami cuba mengejek pelayan chatgpt dan mengembalikan sekeping teks verbatim. Dua perkara terlibat di sini:

  1. Pengepala Respons perlu menetapkan Sambungan untuk kekal hidup dan Jenis Kandungan kepada strim teks/acara.
  2. Selepas menulis respons, ia perlu disiram kepada pelanggan.

Kodnya adalah seperti berikut:

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 ChatCompletionRsprunes := []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)}

Dalam senario sebenar, data yang akan dikembalikan datang daripada perkhidmatan atau fungsi lain panggilan. Jika Masa pemulangan panggilan perkhidmatan atau fungsi ini tidak stabil, yang mungkin menyebabkan pelanggan tidak menerima mesej untuk masa yang lama, jadi kaedah pemprosesan umum ialah:

  1. Panggilan kepada pihak ketiga dibuat dalam goroutine.
  2. Buat pemasa mengikut masa. Tandakan dan hantar mesej kosong kepada pelanggan.
  3. Buat saluran tamat masa untuk mengelakkan masa respons terlalu lama.

Untuk membaca data daripada saluran yang berbeza, pilih ialah kata kunci yang bagus, seperti kod demo ini:

// 声明一个 event channel// 声明一个 time.Tick channel// 声明一个 timeout channelselect {case ev := <h2>Ringkasan </h2> <p style="text-align: justify;"><span style="color: #333333;">Proses menjana dan bertindak balas kepada keseluruhan hasil model bahasa yang besar agak panjang, tetapi respons yang dijana oleh token adalah agak pantas ChatGPT menggabungkan sepenuhnya ciri ini dengan teknologi SSE untuk muncul perkataan demi perkataan . Reply telah mencapai peningkatan kualitatif dalam pengalaman pengguna. </span></p><p style="text-align: justify;"><span style="color: #333333;">Melihat model generatif, sama ada LLAMA/Little Alpaca (tidak tersedia secara komersial) atau Stable Diffusion/Midjourney. Apabila menyediakan perkhidmatan dalam talian, teknologi SSE boleh digunakan untuk meningkatkan pengalaman pengguna dan menjimatkan sumber pelayan. </span></p>

Atas ialah kandungan terperinci Bagaimanakah ChatGPT mengeluarkan perkataan demi perkataan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:51cto.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam