wikitablequestions-llm

Projeto para explorar o dataset do wikipedia chamado WikiTableQuestions. Para acessar os dados, existem duas opções, além de baixar pela interface do site.

O dataset é organizado em alguns diretórios contendo varios datasets sobre diversos contextos, o dado pode ser encontrado no formato .html, .csv ou .tsv. Para esse projeto vamos usa os arquivos .csv e o diretório com identificador 200.

Tabela ./csv/200-csv/0.csv

Year Title Chart-Positions UK Chart-Positions US Chart-Positions NL Comments
1969 Renaissance 60 10
1971 Illusion 1976 (UK)
1972 Prologue
1973 Ashes Are Burning 171
1974 Turn of the Cards 94 1975 (UK)
1975 Scheherazade and Other Stories 48
1977 Novella 46 1977 (January in US, August in UK, as the band moved to the Warner Bros Music Group)
1978 A Song for All Seasons 35 58 UK:Silver
1979 Azure d'Or 73 125
1981 Camera Camera 196
1983 Time-Line 207
2001 Tuscany
2013 Grandine il Vento

Foi usado uma função para percorrer o diretório 200 e adicionando cada dataframe em uma lista: dataframes.py

Como os dataframes são de contextos diferentes, foi usado a LLM para obter algumas informações sobre o contexto de cada dataframe, isso auxiliara para armazenar o dado no banco de dados.

O template do prompt para extrair essas informações foi o seguinte:

prompt_template_str = """\
Give me a Summary and Table Name of the table below with the following JSON format

- The table name must be unique to the table and describe it while being concise.
- Do NOT output a generic table name (e.g. table, my_table).
- Do NOT make the table name one of the following: {exclude_table_name_list}

Table:
{table_str}
"""

Foi criado duas funções: extract_wikitables_infos.py, uma para verificar se o dataframe ja tem informações extraidas para evitar consumo excessivo de requisicoes na API do OpenAI, caso exista é retornado as informações que estão armazenadas no diretório WikiTableQuestions_Infos, e outra para fazer as requisições das informações de cada tabela.

Os resultados podem foram salvos em .json e podem ser vistos no diretório: WikiTableQuestions_Infos

Para configurar e setar os modelos de llm e embedding foi usado as funções: llm_model_handler.py e embed_model_handler.py. Como a aplicação foi executado localmente e no Cloud Run(com poucos recursos), foi escolhido o modelo da OpenAI para otimizar esse gasto de recursos de máquina.

Pontos relevantes dessa parte do fluxo é que foi usado uma configuração de output das interações com o modelo de LLM evitando alucinações e controlando melhor a qualidade do resultado, isso foi configurado usando o parametro output_cls da função LLMTextCompletionProgram.from_defaults(). Essa configuração permite receber uma classe BaseModel do Pydantic que consegue parsear o output e criar uma instancia dessa classe, tudo isso porque é inserido informações dessa classe no template do prompt.

from pydantic import BaseModel, Field


class TableInfo(BaseModel):
    """Information regarding a structured table."""

    table_name: str = Field(
        ..., description="table name (must be underscores and NO spaces)"
    )
    summary: str = Field(
        ..., description="short, concise summary/caption of the table"
    )

Essa informações foram utilizadas como metadados das tabelas de cada .csv, foi usado o sqlalchemy para construir essa parte do fluxo. Para entender melhor como essas tabelas foram criadas: create_sql_tables.py

Tudo é válido somente em tempo de execução, sendo alocado em memória, por se tratar de um caso de experimentação. Então, ao reiniciar a aplicação, boa parte é processada novamente.

Com os metadados e tabelas criados, foi construido uma query pipeline, pode ser visto no arquivo: query_pipeline.py, para manipular os objetos até conseguir a resposta para uma pergunta. Então, ao se fazer uma perguntar. Foi feito algumas manipulações para incluir informações relevantes na busca pela resposta, o template para a pergunta final ficou assim:

    "Given an input question, synthesize a response from the query results.\n"
    "Query: {query_str}\n"
    "SQL: {sql_query}\n"
    "SQL Response: {context_str}\n"
    "Response: "

Veja que é foi contruido uma janela de contexto, incluido, a query, a query SQL e a respota da query SQL, para tentar encontrar a melhor resposta para cada pergunta.

A pipeline pode ser vista pelo diagrama abaixo:

query-pipeline.png

Infraestrutura

TO-DO;

  • Resolver erro da pipeline da query: run-llama/llama_index#10790
  • Construir uma interface user friendly, como streamlit para o usuário passar os textos por ela, ao inves de usar o swagger.
  • Configurar o arize-phoenix para ter observabilidade da performance das tasks de LLM
  • Conseguir usar/carregar dentro da aplicação modelos open-source
    • Como foi usando o Cloud Run para deployar a aplicação, o recurso era limitado, então foi usado a LLM do OpenAI.
  • Usar um banco para salvar os dados e indexes ao inves de salvar tudo em memória
  • Construir uma camada que consiga construir melhor o contexto de cada tabela, sem ser somente fixando o nome das colunas na query, por exemplo, usando similaridade no nome das colunas.