LangChain / app /callbacks /chain_stream.py
dcd018's picture
Initial commit.
b88c922
Raw
History Blame Contribute Delete
1.76 kB
import threading
import queue
import tiktoken
from langchain.chat_models import ChatOpenAI
from langchain.callbacks.manager import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
from openai.error import InvalidRequestError
class ThreadedGenerator:
def __init__(self):
self.queue = queue.Queue()
def __iter__(self):
return self
def __next__(self):
item = self.queue.get()
if item is StopIteration: raise item
return item
def send(self, data):
self.queue.put(data)
def close(self):
self.queue.put(StopIteration)
class ChainStreamHandler(StreamingStdOutCallbackHandler):
def __init__(self, gen):
super().__init__()
self.gen = gen
def on_llm_new_token(self, token: str, **kwargs):
self.gen.send(token)
def run(g, prompts, retries = 0):
try:
chat = ChatOpenAI(
verbose=True,
streaming=True,
callback_manager=CallbackManager([ChainStreamHandler(g)]),
)
chat(prompts)
except InvalidRequestError as e:
if retries >= 10:
raise e
else:
retries += 1
del prompts[-1]
run(g, prompts, retries)
def llm_thread(g, prompts):
encoding = tiktoken.encoding_for_model("gpt-3.5-turbo")
messages = []
tokens = 0
for prompt in prompts:
tokens += len(encoding.encode(prompt.content))
if tokens >= 4096:
break
messages.append(prompt)
try:
run(g, messages)
finally:
g.close()
def chat(prompts):
g = ThreadedGenerator()
threading.Thread(target=llm_thread, args=(g, prompts)).start()
return g