CLASSFUNC BLOG
We Share Our Knowledge
Hiểu về stream response
Lê Thành
5 Th01 2024 10:05

AI đang phát triển rất nhanh ở thời điểm viết bài viết này. Thông tin dữ liệu không ngừng tăng lên khi có BigData, AI, ...

Việc stream dữ liệu là một phần quan trọng của hệ thống, tăng thêm trải nghiệm tuyệt vời cho người dùng.

ClassFunc cũng không ngừng nâng cao kỹ năng, bắt kịp xu hướng AI để đưa ra các sản phẩm công nghệ phục vụ cuộc sống.

Bài viết này chia sẻ về mặt kỹ thuật, giúp những bạn nào chưa biết sẽ có thể thực hiện được stream response đơn giản nhất có thể.

(code sử dụng trong bài viết là Python)

Các keyword khi làm việc với stream response:

  1. Connection: keep-alive
  2. python generator: yield 'data: {}\n'.format(text)
  3. response header: mimetype="text/event-stream"

Python được sử dụng nhiều trong AI, vì thư viện support có nhiều, cộng đồng lớn và được update nhanh.

Trong dự án với khách hàng và của ClassFunc, Flask là 1 trong những framework được ClassFunc tin dùng.

Connection: keep-alive

  • Cài đặt biến môi trường của flask: .flaskenv với biến FLASK_APP=wsgi:app
  • Trong file wsgi.py có đoạn code như sau:
from werkzeug.serving import WSGIRequestHandler # mặc định protocol_version là 1.0, cần set là 1.1 WSGIRequestHandler.protocol_version = "HTTP/1.1" # start app from flaskr import create_app app = create_app()

stream_with_context

ClassFunc sử dụng LLAMAINDEX framework cho việc index tài liệu phục vụ cho Q&A, Search và tương tác với LLM (OPENAI, VertexAI,...)

Code để thực hiện được stream trong Flask như sau:

from flask import stream_with_context, Response @app.route("/stream-response", methods=['POST']) def query_all(): queryEngine = index.as_query_engine( streaming=True # báo với LLM là trả về stream cho tôi ) streamResponse = queryEngine.query(userQuery) def gen(): for text in streamResponse.response_gen: yield 'data: {}\n'.format(text) # 'data:' quan trọng cho client hiểu để hiển thị return Response( stream_with_context(gen()), mimetype="text/event-stream" # cần thiết để client nhận biết đây là text được stream )

Khởi động dev với câu lệnh flask run, query thì response header sẽ có dạng như sau:

Screenshot 2024-01-05 at 16.29.41.png

docker & gunicorn

Khi deploy môi trường production, ClassFunc sử dụng gunicorn để khởi động app, để keep-alive ta có đoạn như sau trong file Docker:

EXPOSE 8080 CMD exec gunicorn --bind :8080 --workers 1 --threads 8 --timeout 0 --keep-alive 5 wsgi:app

Lời kết:

Nắm được tầm quan trọng của việc dữ liệu được stream sẽ là 1 bước đệm lớn tăng trải nghiệm người dùng tuyệt vời và chuyên nghiệp hơn.

Chúc các bạn thành công.