Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Erro na execução dessa aula (This model's maximum context length is 16385 tokens.)

Não consegui reproduzir o exemplo dessa aula.

A seguinte mensagem de erro é mostrada: openai.BadRequestError: Error code: 400 - {'error': {'message': "This model's maximum context length is 16385 tokens. However, your messages resulted in 18617 tokens. Please reduce the length of the messages.", 'type': 'invalid_request_error', 'param': 'messages', 'code': 'context_length_exceeded'}}

Quando eu uso o "print(db.as_retriever().get_relevant_documents(query))", praticamente é mostrado todo o texto do documento, o que a meu ver deveriam mostrar apenas a parte de 1000 caracteres que fazia sentido com a query.

from langchain.globals import set_debug  # For debugging
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.chains import RetrievalQA

from utils import LLMUtils

# set_debug(True)

llm = LLMUtils().get_openai_llm()

text_loader = TextLoader("data/GTB_gold_Nov23.txt", encoding='utf-8')
documents = text_loader.load()
splitter = CharacterTextSplitter(chunk_size = 1000, chunk_overlap=200)
texts = splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()
db = FAISS.from_documents(texts, embeddings)

qa_chain = RetrievalQA.from_chain_type(llm, retriever = db.as_retriever())

query = 'Como devo proceder caso tenha um item comprado roubado'

# print(db.as_retriever().get_relevant_documents(query))

result = qa_chain.invoke({'query': query})
print(result)

O LLMUtils ali é só uma classe que usei para organizar melhor o código, mas por via das dúvidas, passo aqui também:

from langchain_openai import ChatOpenAI
from langchain_community.llms import Ollama
from dotenv import load_dotenv
import os


class LLMUtils:
    __temperature = 0
    __model = ''
    __api_key = os.getenv('OPENAI_API_KEY')

    def __init__(self, temperature=1, model='gpt-3.5-turbo'):
        load_dotenv()
        self.__temperature = temperature
        self.__model = model

    def get_openai_llm(self) -> ChatOpenAI:
        llm = ChatOpenAI(
            temperature=self.__temperature,
            model=self.__model,
            api_key=self.__api_key
        )
        return llm

Nota que utilizei o código da aula (com ctrl+c e ctrl+v) e também deu o mesmo problema.

[EDIT]

Eu continuei o curso e na proxima aula é usado o PyPDFLoader para carregar os arquivos, e com ele funcionou.

text_loader = TextLoader("data/GTB_gold_Nov23.txt", encoding='utf-8')
text_loader = PyPDFLoader("data/GTB_gold_Nov23.pdf")
documents = text_loader.load()
splitter = CharacterTextSplitter(chunk_size = 1000, chunk_overlap=200)
texts = splitter.split_documents(documents)

print(texts[1])

Nesse trecho, quando comenta uma das duas linhas do textloader, temos comportamentos diferentes.

No PyPdfLoader, retorna um texto menor, com a quebra do splitter certinho. No entanto, no TextLoader ainda dá problema, nesse caso, list index out of range, pq o splitter não conseguiu quebrar.

Alguém imagina o que pode estar ocorrendo?

3 respostas

Oii Josiel, tudo bem?

Isso acontece porque o modelo da OpenAI tem um limite de tokens que pode processar de uma vez, e o seu texto está excedendo esse limite.

  1. Verifica o tamanho dos chunks: O erro diz que a quantidade de tokens está excedendo o limite. Mesmo que você tenha configurado o CharacterTextSplitter para dividir o texto em chunks de 1000 caracteres, é possível que a quantidade de tokens gerada ainda seja muito grande. Tente reduzir o chunk_size para algo menor, como 500 caracteres.

    splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=100)
    texts = splitter.split_documents(documents)
    
  2. Verifique o encoding: Como você mencionou que o TextLoader está funcionando de forma diferente do PyPDFLoader, certifique-se de que o encoding do arquivo de texto está correto. Você já está usando encoding='utf-8', o que é ótimo, mas vale a pena verificar se o arquivo de texto está realmente bem formatado.

  3. Utilize um modelo diferente: Se possível, tente usar um modelo com maior capacidade de tokens, como o gpt-4-32k, se estiver disponível para você. Isso pode ajudar a lidar com textos maiores.

Espero que ajude.

Um abraço e bons estudos.

solução!

Boa noite,

Eu estava com o mesmo problema, e o que aconteceu no meu caso é que o CharacterTextSplitter não estava dividindo o texto, pois o texto não possuía os caracteres padrão do parâmetro "separator", que são "\n\n". Pelo que entendi, para não quebrar "no meio" ele usa o separator para saber onde deve quebrar quando alcança o chunk_size. Acredito que é para não quebrar parágrafos ou frases no meio. Acrescentando o parâmetro separator com um ponto, ele vai quebrar no fim da frase. Ex: CharacterTextSplitter(separator=".", chunk_size=1000).

Usei o seguinte código para verificar se o texto estava sendo quebrado:

print(f"Total de pedaços: {len(textos)}")
for i, texto in enumerate(textos):
    print(f"Pedaço {i+1}: {len(texto.page_content)} caracteres")

No meu caso, não estava. Funcionou depois que mudei a chamada para:

quebrador = CharacterTextSplitter(separator=".", chunk_size=1000)

Isso para o TextLoader. Já para o PyPDFLoader, não deu o problema.

Daniela, era isso mesmo. Usei o "." como separador ali, e funcionou como o esperado.

O comportamento era o que você mencionou também, como o texto não tinha quebras de linhas, não chegou a quebrar nada no splitter.

Muito obrigado.