文章目錄
- 1. 非流式輸出與流式輸出概述
- 2. 非流式輸出
- 2.1 代碼實例1
- 2.2 代碼實例2
- 3. 流式輸出
- 3.1 流式輸出的定義和作用
- 3.2 流式輸出適用的場景
- 3.3 流式輸出的實現方式與實現技術
- 3.4 代碼實例3
- 3.5 代碼實例4
- 4. 小結
1. 非流式輸出與流式輸出概述
大模型收到輸入后并不是一次性生成最終結果,而是逐步地生成中間結果,最終結果由中間結果拼接而成。
相比非流式輸出,流式輸出可以實時地將中間結果返回,您可以在模型進行輸出的同時進行閱讀,減少等待模型回復的時間;并且當輸出內容較長時,有效降低請求超時的風險。
本文給出了使用Python requests庫調用大型語言模型(LLM)API的非流式輸出與流式輸出的簡單介紹和代碼實例。
2. 非流式輸出
2.1 代碼實例1
下面直接給出非流式輸出的代碼實例。可以結合代碼的運行輸出過程來體驗非流式輸出那種讓用戶巴巴干等著的那種用戶體驗效果。
import requestsAUTH_VALUE = "sk-..." # 替換為你的API Key
# api = "https://api.openai.com/v1/chat/completions"
url = "https://api.siliconflow.cn/v1/chat/completions"
headers = {"Content-Type": "application/json","Authorization": f"Bearer {AUTH_VALUE}"
}while True:# 獲取用戶輸入question = input("\n請輸入您的問題 (Quit by typing q): ").strip()if question.lower() == 'q':print("程序已退出")breakjson_data = {"model": "deepseek-ai/DeepSeek-V3","messages": [{"role": "user", "content": question}],"stream": False, # 非流式輸出 default: false# "max_tokens": 2048, # 最大輸出長度 (2048), default: 512, Required range: 1 < x < 8192# "temperature": 0.7, # Determines the degree of randomness in the response. default: 0.7# "top_p": 0.7, # 采樣參數 default: 0.7# "top_k": 50, # 采樣參數 default: 50# "frequency_penalty": 0.5, # 重復懲罰系數 default: 0.5# "n": 1, # Number of generations to return. default: 1# "response_format": {# "type": "text" # The type of the response format.# }}try:# 發送非流式請求response = requests.post(url=url, headers=headers, json=json_data, stream=False) response.raise_for_status() # 檢查響應狀態response.encoding = "utf-8"# print(response.text)# print(response.status_code)print(response.json())except requests.RequestException as e: # 捕獲網絡異常error_msg = f"請求錯誤: {str(e)}\n"print(error_msg)
運行程序,某次對話輸出如下:
請輸入您的問題 (Quit by typing q): 什么是分布式數據庫系統?
{'id': '01954f50cae8185aeea97c360069222d', 'object': 'chat.completion', 'created': 1740792449, 'model': 'deepseek-ai/DeepSeek-V3', 'choices': [{'index': 0, 'message': {'role': 'assistant', 'content': '**分布式數據庫系統(Distributed Database System, DDBS)** 是一種由多個相互連接的數據庫組成的系統,這些數據庫分布在不同的物理位置或節點上,但對外提供統一的訪問接口和數據管理功能。分布式數據庫系統的核心目標是將數據存儲和處理分布到多個節點上,以提高系統的可擴展性、可靠性和性能。\n\n### 分布式數據庫系統的主要特征:\n1. **數據分布**:數據被分散存儲在不同的節點上,可以是不同的地理位置或服務器。\n2. **數據透明性**:用戶或應用程序無需知道數據具體存儲在哪里,系統會自動處理數據的定位和訪問。\n3. **節點自治性**:每個節點可以獨立運行,擁有自己的局部數據庫管理系統(DBMS)。\n4. **網絡通信**:節點之間通過網絡進行通信,協調數據的存儲和查詢。\n5. **一致性控制**:系統需要確保數據的一致性,通常通過分布式事務管理、副本控制等機制實現。\n6. **高可用性和容錯性**:由于數據分布在多個節點上,系統可以容忍部分節點的故障,從而提高整體可用性。\n\n### 分布式數據庫系統的架構:\n1. **全局模式**:描述整個分布式數據庫的邏輯結構和數據分布。\n2. **局部模式**:描述每個節點上的局部數據庫結構。\n3. **分布式事務管理器**:負責協調跨節點的事務,確保事務的原子性和一致性。\n4. **數據復制和分片**:\n - **復制**:數據在多個節點上存儲副本,以提高可用性和讀取性能。\n - **分片**:將數據分割成多個片段,分布到不同的節點上,以提高存儲和處理的效率。\n\n### 分布式數據庫系統的優點:\n1. **可擴展性**:可以通過增加節點來擴展存儲容量和處理能力。\n2. **高性能**:數據可以就近訪問,減少延遲,并通過并行處理提升查詢性能。\n3. **高可用性**:數據的多副本存儲和節點冗余可以提高系統的容錯能力。\n4. **靈活性**:可以根據需求動態調整數據的分布和復制策略。\n\n### 分布式數據庫系統的挑戰:\n1. **復雜性**:系統設計、實現和管理比集中式數據庫更為復雜。\n2. **一致性維護**:在分布式環境中,保證數據一致性需要復雜的協議和算法(如Paxos、Raft等)。\n3. **網絡延遲和故障**:網絡通信可能成為性能瓶頸,網絡故障可能導致數據不可用或丟失。\n4. **安全性**:分布式環境下的數據安全性和隱私保護面臨更大挑戰。\n\n### 常見的分布式數據庫系統:\n- **NoSQL數據庫**:如Cassandra、MongoDB、Redis等。\n- **NewSQL數據庫**:如Google Spanner、CockroachDB等。\n- **分布式關系數據庫**:如MySQL Cluster、PostgreSQL的分布式擴展等。\n\n分布式數據庫系統是處理大規模數據和高并發場景的重要技術,廣泛應用于互聯網、金融、物聯網等領域。'}, 'finish_reason': 'stop'}], 'usage': {'prompt_tokens': 8, 'completion_tokens': 600, 'total_tokens': 608}, 'system_fingerprint': ''}
下面的內容是對上面代碼實例1的輸出內容的進一步提取的到結果
**分布式數據庫系統(Distributed Database System, DDBS)** 是一種由多個相互連接的數據庫組成的系統,這些數據庫分布在不同的物理位置或節點上,但對外提供統一的訪問接口和數據管理功能。分布式數據庫系統的核心目標是將數據存儲和處理分
布到多個節點上,以提高系統的可擴展性、可靠性和性能。### 分布式數據庫系統的主要特征:
1. **數據分布**:數據被分散存儲在不同的節點上,可以是不同的地理位置或服務器。
2. **數據透明性**:用戶或應用程序無需知道數據具體存儲在哪里,系統會自動處理數據的定位和訪問。
3. **節點自治性**:每個節點可以獨立運行,擁有自己的局部數據庫管理系統(DBMS)。
4. **網絡通信**:節點之間通過網絡進行通信,協調數據的存儲和查詢。
5. **一致性控制**:系統需要確保數據的一致性,通常通過分布式事務管理、副本控制等機制實現。
6. **高可用性和容錯性**:由于數據分布在多個節點上,系統可以容忍部分節點的故障,從而提高整體可用性。### 分布式數據庫系統的架構:
2. **局部模式**:描述每個節點上的局部數據庫結構。
3. **分布式事務管理器**:負責協調跨節點的事務,確保事務的原子性和一致性。
4. **數據復制和分片**:- **復制**:數據在多個節點上存儲副本,以提高可用性和讀取性能。- **分片**:將數據分割成多個片段,分布到不同的節點上,以提高存儲和處理的效率。### 分布式數據庫系統的優點:
1. **可擴展性**:可以通過增加節點來擴展存儲容量和處理能力。
2. **高性能**:數據可以就近訪問,減少延遲,并通過并行處理提升查詢性能。
3. **高可用性**:數據的多副本存儲和節點冗余可以提高系統的容錯能力。
4. **靈活性**:可以根據需求動態調整數據的分布和復制策略。### 分布式數據庫系統的挑戰:
1. **復雜性**:系統設計、實現和管理比集中式數據庫更為復雜。
3. **網絡延遲和故障**:網絡通信可能成為性能瓶頸,網絡故障可能導致數據不可用或丟失。
4. **安全性**:分布式環境下的數據安全性和隱私保護面臨更大挑戰。### 常見的分布式數據庫系統:
- **NoSQL數據庫**:如Cassandra、MongoDB、Redis等。
- **NewSQL數據庫**:如Google Spanner、CockroachDB等。
- **分布式關系數據庫**:如MySQL Cluster、PostgreSQL的分布式擴展等。分布式數據庫系統是處理大規模數據和高并發場景的重要技術,廣泛應用于互聯網、金融、物聯網等領域。
2.2 代碼實例2
import requestsAUTH_VALUE = "sk-..." # 替換為你的API Key
# api = "https://api.openai.com/v1/chat/completions"
url = "https://api.siliconflow.cn/v1/chat/completions"
headers = {"Content-Type": "application/json","Authorization": f"Bearer {AUTH_VALUE}"
}
while True:# 獲取用戶輸入question = input("\n請輸入您的問題 (Quit by typing q): ").strip()if question.lower() == 'q':print("程序已退出")breakjson_data = {"model": "deepseek-ai/DeepSeek-V3","messages": [{"role": "user", "content": question}],"stream": False, # 非流式輸出 default: false}try:# 發送非流式請求response = requests.post(url=url, headers=headers, json=json_data, stream=False) response.raise_for_status() # 檢查響應狀態response.encoding = "utf-8"print("\nReply: \n")# print(response.text)# print(response.status_code)# print(response.json())print(response.json()["choices"][0]["message"]["content"])except requests.RequestException as e: # 捕獲網絡異常error_msg = f"請求錯誤: {str(e)}\n"print(error_msg)
運行程序,某次對話輸出如下:
請輸入您的問題 (Quit by typing q): 簡述數據庫管理系統的存儲引擎的概念和作用。Reply: 數據庫管理系統(DBMS)的存儲引擎(Storage Engine)是數據庫系統中負責數據的存儲、檢索和管理的核心組件。它直接與底層存儲介質(如磁盤、內存等)交互,為數據庫提供數據的高效存儲和訪問能力。### 存儲引擎的概念:
存儲引擎是數據庫管理系統中的一個模塊或子系統,負責數據的物理存儲和訪問。它是數據庫系統的“后端”,負責管理數據的存儲結構、索引、事務處理、并發控制、恢復機制等。不同的存儲引擎可能采用不同的存儲結構和算法,以優化特定類型的工作負
載。### 存儲引擎的作用:
1. **數據存儲**:存儲引擎負責將數據庫中的數據以特定的格式存儲在磁盤或內存中,并管理數據的物理布局。它使用各種數據結構(如B樹、哈希表等)來組織數據,以提高存儲和檢索效率。2. **數據檢索**:存儲引擎處理查詢請求,根據查詢條件從存儲介質中快速檢索數據。它支持多種索引類型(如B+樹索引、全文索引等),以加速數據查找。3. **事務管理**:許多存儲引擎支持事務處理,確保數據的原子性、一致性、隔離性和持久性(ACID特性)。事務管理包括日志記錄、回滾機制和鎖管理等。4. **并發控制**:存儲引擎管理多個用戶或應用程序對數據的并發訪問,確保數據的一致性和完整性。常見的并發控制機制包括鎖機制、多版本并發控制(MVCC)等。5. **數據恢復與備份**:存儲引擎支持數據恢復功能,通過日志文件(如redo log、undo log)在系統崩潰后恢復數據。它還支持數據的備份和恢復操作,以保障數據的安全性。6. **性能優化**:不同的存儲引擎針對不同的應用場景進行了優化。例如,某些存儲引擎適用于高并發的OLTP(聯機事務處理)系統,而另一些則更適合大數據量的OLAP(聯機分析處理)系統。用戶可以根據需求選擇合適的存儲引擎以獲得最佳性能。 ### 常見的存儲引擎:
- **InnoDB**(MySQL):支持事務、行級鎖、外鍵約束等,適合OLTP場景。
- **MyISAM**(MySQL):不支持事務和行級鎖,但具有較高的讀取性能,適合讀密集型的應用。
- **RocksDB**:基于LSM樹的存儲引擎,適用于寫密集型的高吞吐量場景。
- **WiredTiger**(MongoDB):支持文檔級別的并發控制和壓縮,適合NoSQL數據庫。### 總結:
存儲引擎是數據庫管理系統的核心組件,負責數據的存儲、檢索、事務管理和并發控制等任務。不同的存儲引擎提供了不同的功能和優化策略,用戶可以根據具體需求選擇最適合的存儲引擎,以提高數據庫的性能和可靠性。
3. 流式輸出
3.1 流式輸出的定義和作用
流式輸出是一種處理數據的方式,允許程序在數據生成的同時逐步接收和處理數據,而不是等待所有數據完成后再處理。對于聊天模型而言,流式傳輸可以讓用戶實時看到模型的輸出,而不是等到整個響應生成完畢?。流式輸出的主要作用包括:
- 實時反饋?:用戶可以即時看到模型的輸出,而不是等待整個響應生成完畢。
- ?減少等待時間?:用戶可以在模型進行輸出的同時閱讀內容,減少等待時間。
- ?降低超時風險?:當輸出內容較長時,可以有效降低請求超時的風險?。
- 在需要實時處理大量數據的場景中,如語音識別、視頻分析等,使用stream參數可以顯著提高效率和性能。例如,在語音識別應用中,流式傳輸可以實時處理用戶的語音輸入,而不需要等待整個錄音文件處理完畢。
- 在大數據處理和分析中,流式傳輸可以分批處理數據,減少內存消耗,提高處理速度?
3.2 流式輸出適用的場景
流式輸出通常用于以下幾種場景:
- 實時數據更新,例如股票行情、社交媒體的實時消息流。
- 大數據處理,例如長時間查詢或計算的結果逐步傳輸。
- 節省帶寬,在網絡環境不佳的情況下減少一次性傳輸大量數據的壓力。
3.3 流式輸出的實現方式與實現技術
流式輸出的實現方式包括同步流式傳輸和異步流式傳輸:
- 同步流式傳輸?:直接從模型的stream方法中獲取數據,每次返回一個完整的輸出。
- 異步流式傳輸?:適用于需要更高并發性的應用,通過astream方法異步地接收模型的輸出?。
在具體實現流式輸出時,常用的技術包括:
- HTTP 分塊傳輸(Chunked Transfer Encoding):HTTP 協議支持將數據以分塊的方式傳輸,每個數據塊都會攜帶長度信息。后端可以在響應完成之前,逐步地發送多個數據塊給前端。
- Server-Sent Events (SSE):SSE 是一種在服務器向客戶端推送事件的技術,適合實時性要求高但傳輸頻率不高的場景。
- WebSocket:WebSocket 是一個全雙工協議,允許服務器和客戶端相互通信,適合高頻率的實時數據傳輸。
通過 OpenAI 兼容方式開啟流式輸出十分簡便,只需在請求參數中設置 stream 為 true 即可。當然如果使用requests.post()請求方法,則亦應設置requests.post()方法的stream=True,以啟用流式傳輸。針對IO之輸出的緩沖功能,為即時顯示各個響應回來的token內容(chunk),使用print()在終端輸出時,建議加上參數flush=True以配合流式輸出,即print(chunk, end='', flush=True)
;如果是將各個響應回來的token內容(chunk)進行持久化保存,則寫入文件后,如file.write(chunk)
,也應該即時刷新輸出緩沖區,如file.flush()
。當然如此將各個token內容逐個寫入文件導致了頻繁的文件IO,此時就應該現在內存中得到一個完整的響應內容后,如full_content += chunk.choices[0].delta.content
,再一次性地寫入文件中。詳情請參見以下示例代碼。
3.4 代碼實例3
仍然先直接給出下面的流式輸出的代碼實例。可以結合代碼的運行輸出過程來體驗流式輸出那種一個詞一個詞蹦出來的動態效果。僅此一點,用戶體驗大大提升。
import requests
import jsonAUTH_VALUE = "sk-..." # 替換為你的API Key
# url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
# api = "https://api.openai.com/v1/chat/completions"
url = "https://api.siliconflow.cn/v1/chat/completions"
headers = {"Content-Type": "application/json","Authorization": f"Bearer {AUTH_VALUE}"
}while True:# 獲取用戶輸入question = input("\n請輸入您的問題 (Quit by typing q): ").strip()if question.lower() == 'q':print("程序已退出")breakjson_data = {"model": "deepseek-ai/DeepSeek-V3","messages": [{"role": "user", "content": question}],"stream": True, # 流式輸出 default: false}try:# 發送流式請求response = requests.post(url=url, headers=headers, json=json_data, stream=True) # stream=True 啟用流式傳輸response.raise_for_status() # 檢查響應狀態response.encoding = "utf-8"print("\nReply: \n")print(response.text)except requests.RequestException as e: # 捕獲網絡異常error_msg = f"請求錯誤: {str(e)}\n"print(error_msg)
運行程序,某次對話的部分輸出如下:
請輸入您的問題 (Quit by typing q): 請對烏克蘭總統澤連斯基給出一個簡要評價。Replydata: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"","reasoning_content":null,"role":"assistant"},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":0,"total_tokens":15}}data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"烏克蘭","reasoning_content":null},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":1,"total_tokens":16}}data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"總統澤","reasoning_content":null},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":3,"total_tokens":18}}data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"連斯基","reasoning_content":null},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":5,"total_tokens":20}}data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"自201","reasoning_content":null},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":7,"total_tokens":22}}data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"9年","reasoning_content":null},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":9,"total_tokens":24}}data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"擔任","reasoning_content":null},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":10,"total_tokens":25}}data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"總統以來","reasoning_content":null},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":12,"total_tokens":27}}data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":",在國際","reasoning_content":null},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":14,"total_tokens":29}}......data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"得以實現","reasoning_content":null},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":155,"total_tokens":170}}data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"。","reasoning_content":null},"finish_reason":null,"content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":156,"total_tokens":171}}data: {"id":"01954fb21a95199efa284b55fb43912a","object":"chat.completion.chunk","created":1740798827,"model":"deepseek-ai/DeepSeek-V3","choices":[{"index":0,"delta":{"content":"","reasoning_content":null},"finish_reason":"stop","content_filter_results":{"hate":{"filtered":false},"self_harm":{"filtered":false},"sexual":{"filtered":false},"violence":{"filtered":false}}}],"system_fingerprint":"","usage":{"prompt_tokens":15,"completion_tokens":156,"total_tokens":171}}data: [DONE]
由上面print(response.text)
語句的輸出可知,AI大模型的流式輸出單位是token?。在自然語言處理中,token是對輸入文本進行分割和編碼時的最小單位,它可以是一個單詞、子詞或字符,具體取決于token化過程?。流式輸出是指模型在生成結果的過程中逐步返回中間結果,而不是等到所有結果生成完畢后再返回最終結果。這種方式可以實時返回中間結果,減少用戶的等待時間,并降低請求超時的風險?。
3.5 代碼實例4
下面對上面的實例代碼增加了對流式輸出的token內容進行提取的部分。
import requests
import jsonAUTH_VALUE = "sk-..." # 替換為你的API Key
# api = "https://api.openai.com/v1/chat/completions"
url = "https://api.siliconflow.cn/v1/chat/completions"
headers = {"Content-Type": "application/json","Authorization": f"Bearer {AUTH_VALUE}"
}
while True:# 獲取用戶輸入question = input("\n請輸入您的問題 (Quit by typing q): ").strip()if question.lower() == 'q':print("程序已退出")breakjson_data = {"model": "deepseek-ai/DeepSeek-V3","messages": [{"role": "user", "content": question}],"stream": True, # 流式輸出 default: false}try:# 發送流式請求response_stream = requests.post(url=url, headers=headers, json=json_data, stream=True) # stream=True 啟用流式傳輸response_stream.raise_for_status() # 檢查響應狀態# response.encoding = "utf-8"print("\nReply: \n")# print(response.text)# 處理流式響應for line in response_stream.iter_lines(): # 逐行處理響應數據if line:line = line.decode('utf-8')if line.startswith('data: '):if line == 'data: [DONE]': # Stream terminates with "data: [DONE]"continuetry:content = json.loads(line[6:]) # 去掉每一行的 'data: ' 前綴if content['choices'][0]['delta'].get('content'):chunk = content['choices'][0]['delta']['content']print(chunk, end='', flush=True)except json.JSONDecodeError as e: # 處理 JSON 解析錯誤print("JSONDecodeError: " + e)continueexcept requests.RequestException as e: # 捕獲網絡異常error_msg = f"請求錯誤: {str(e)}\n"print(error_msg)finally:# 在處理完流式數據后,關閉連接釋放資源response_stream.close()
下面是運行上面實例的一次會話情況。
請輸入您的問題 (Quit by typing q): 請對烏克蘭總統澤連斯基給出一個簡要中肯的評價。Reply:烏克蘭總統弗拉基米爾·澤連斯基(Volodymyr Zelensky)是一位備受關注的政治人物。他在2019年以政治素人的身份高票當選,此前以喜劇演員和政治諷刺節目《人民公仆》中的總統角色聞名。澤連斯基上任后的執政經歷復雜且充滿挑戰。他初期承諾打擊腐敗、推動國內改革,并尋求解決東部頓巴斯地區沖突,但在實施過程中面臨諸多阻力。2022年俄羅斯全面入侵烏克蘭后,澤連斯基的領導力得到國際社會的廣泛認可。他展現出堅定的抗敵決心,積極尋求
國際支持,并通過靈活的外交手段和公開演講贏得了全球輿論的同情與支持。他的果斷決策和團結民眾的能力在戰爭期間發揮了重要作用,但也面臨對內政經濟重建和外交平衡的長期挑戰。總體而言,澤連斯基是一位在危機中崛起的領導人,其執政表現受到戰爭背景的深刻影響,未來評價將取決于烏克蘭的國家命運與他的政策成效。
----------------------------------------
輸出語句print(chunk, end='', flush=True)
中的參數flush=True 在 print 函數中的作用是強制刷新輸出緩沖區,確保打印的內容立即顯示。這在需要實時輸出信息、調試程序或確保關鍵日志即時寫入時非常有用。
Python 的標準輸出(例如 print)通常是緩沖的,這意味著數據先寫入內存中的緩沖區,然后再寫入到最終目的地(如控制臺、文件等)。通過調用 sys.stdout.flush() 或使用 flush=True 參數,可以強制立即刷新緩沖區,將數據寫入到目的地。
在使用Python的requests庫進行HTTP請求時,如果你希望以流式(streaming)的方式處理響應,這樣可以避免一次性將整個響應內容加載到內存中,特別是在處理大文件或實時數據流時非常有用。
使用stream=True參數在requests.post()中開啟流式響應后,requests庫就會以流的形式接收數據,而不是一次性讀取所有數據。
由于流式響應是分塊(chunk)返回的,你可以通過迭代響應的iter_content()或iter_lines()方法來逐塊處理數據。
如果你知道響應是以行為單位的(例如,文本數據),可以使用iter_lines(),它會按行返回數據。
for line in response.iter_lines():if line: # 過濾掉空行decoded_line = line.decode('utf-8')print(decoded_line)
如果響應回來的數據是固定大小的分塊(chunk),可以使用使用iter_content()來逐塊處理數據。
for chunk in response.iter_content(chunk_size=8192):# 處理每個塊,例如解碼為字符串并打印if chunk: # 確保塊不為空decoded_chunk = chunk.decode('utf-8')print(decoded_chunk)
4. 小結
流式輸出(Streaming Output)是一種使后端將數據分塊、逐步發送到前端的技術。通過這種方法,前端應用能夠即時接收和渲染數據,不必等到整個響應體生成完畢后再處理。
流式輸出是一種強大的工具,能夠顯著改善數據傳輸體驗,特別適用于實時和大數據場景。
市面上的GPT在回復我們的問題的時候基本上都是采用類似對話的流式傳輸方式。數據在生成后立即被發送給用戶,而不是等待所有數據都生成完畢后再一次性發送。
流式 API 提供了即時響應的體驗,允許用戶在內容生成過程中即時查看部分結果。相比等待整個響應完成,流式輸出極大提高了用戶體驗。適用于多種場景,例如:
- 實時內容生成:用戶在等待生成大段文本時,可以即時查看部分內容。
- 漸進式加載:減少等待時間,提升交互性。
- 流式處理:流式 API 讓開發者能夠邊生成邊處理數據,尤其適用于實時應用。
關于流式輸出的深入介紹,可以仔細閱讀樂予呂在“稀土掘金”(一個幫助開發者成長的社區)上寫的技術文章《解讀大型語言模型(LLM)API:了解流式輸出的工作原理》,
文章鏈接:https://juejin.cn/post/7436761388851937319