1 pontos por GN⁺ 2024-11-19 | 1 comentários | Compartilhar no WhatsApp
  • O Fast GraphRAG é um framework simplificado de GraphRAG para workflows de busca baseados em agentes com alta precisão e interpretabilidade, focado em adicionar RAG avançado ao pipeline de busca sem precisar construir diretamente workflows complexos de agentes
  • Ele transforma o grafo de conhecimento em uma forma navegável por humanos, permitindo consulta, visualização e atualização, além de gerar e refinar automaticamente o grafo de acordo com exigências de domínio e ontologia
  • Para responder consultas, usa exploração de grafo baseada em personalized PageRank para encontrar informações relevantes, e o README aponta o artigo do HippoRAG como visão geral dessa abordagem
  • No exemplo de custo com The Wizard of Oz, o fast-graphrag é apresentado com custo de $0.08 e o graphrag com $0.48, afirmando que a redução de custo de 6x melhora ainda mais à medida que o tamanho dos dados e o número de inserções aumentam
  • Funciona com Python 3.10.1 ou superior, oferece instalação pelo código-fonte e via PyPI, e após configurar a chave da API da OpenAI permite inserir documentos e fazer consultas, mantendo automaticamente o conhecimento no mesmo diretório de trabalho

Framework de busca oferecido pelo Fast GraphRAG

  • O Fast GraphRAG é um framework de GraphRAG voltado para conhecimento interpretável e depurável
  • O grafo apresenta o conhecimento em uma forma que humanos podem explorar, oferecendo suporte às seguintes tarefas
    • consulta
    • visualização
    • atualização
  • O foco é oferecer recursos avançados de RAG ao mesmo tempo em que reduz a carga de construir e projetar diretamente workflows de agentes

Principais recursos

  • Foi projetado para operar em larga escala de forma rápida e de baixo custo, buscando reduzir exigências pesadas de recursos e custos
  • Dá suporte a dados dinâmicos, gerando e refinando automaticamente o grafo conforme os requisitos de domínio e ontologia
  • Suporta atualizações incrementais quando os dados mudam, permitindo atualizações em tempo real
  • Oferece exploração inteligente que aumenta precisão e confiabilidade usando exploração de grafo baseada em PageRank
  • No geral, é assíncrono e busca workflows robustos e previsíveis com suporte completo a tipos

Exemplo de custo

  • No exemplo com The Wizard of Oz, o custo do fast-graphrag é apresentado como $0.08 e o do graphrag como $0.48
  • O README descreve isso como uma redução de custo de 6x e diz que o efeito melhora ainda mais conforme crescem o tamanho dos dados e o número de inserções

Instalação e fluxo de execução

  • As formas recomendadas de instalação se dividem entre instalação a partir do código-fonte para desempenho e instalação via PyPI para estabilidade
    • Instalação pelo código-fonte: clonar o repositório e depois executar poetry install
    • Instalação via PyPI: pip install fast-graphrag
  • O exemplo de início rápido primeiro define a variável de ambiente OPENAI_API_KEY
  • Depois de baixar o texto de A Christmas Carol, o GraphRAG é inicializado em código Python
  • A inicialização de exemplo inclui os seguintes valores
    • working_dir="./book_example"
    • domain para analisar personagens, interações, lugares e relações da história
    • uma lista de consultas de exemplo
    • tipos de entidade ["Character", "Animal", "Place", "Object", "Activity", "Event"]
  • O documento é inserido com grag.insert(f.read()), e o resultado da consulta é exibido com grag.query("Who is Scrooge?").response
  • Se for inicializado novamente no mesmo diretório de trabalho, o conhecimento é preservado automaticamente
  • Para controlar o número de tarefas simultâneas de LLM, como no uso de modelos locais, é possível definir opcionalmente uma variável de ambiente como CONCURRENT_TASK_LIMIT=8

Exemplos e opções de configuração

  • A pasta examples oferece tutoriais de casos de uso comuns da biblioteca
  • custom_llm.py é um exemplo simples de como configurar separadamente um modelo de linguagem e embeddings compatíveis com a API da OpenAI
  • checkpointing.ipynb aborda o uso de checkpoints para evitar danos irreversíveis aos dados
  • query_parameters.ipynb trata de vários parâmetros de consulta e mostra como incluir referências das informações usadas na resposta com with_references=True

Filosofia de design e método de exploração

  • O objetivo é aumentar o número de aplicações GenAI bem-sucedidas e, para isso, a proposta é criar ferramentas de memória e dados que permitam a apps com LLM usar pipelines de busca especializados sem a necessidade de configurar e manter workflows complexos de agentes
  • O Fast GraphRAG explora o grafo com o algoritmo personalized PageRank para encontrar as informações mais relevantes para responder à consulta atual
  • Como visão geral de por que essa abordagem funciona, é indicado como referência o artigo do HippoRAG

Open source e serviço gerenciado

  • O repositório é oferecido sob a licença MIT, com detalhes em LICENSE.txt
  • Também é oferecido um serviço gerenciado como forma de começar com rapidez e confiabilidade
  • No serviço gerenciado, os primeiros 100 pedidos por mês são gratuitos, e depois a cobrança é feita com base no uso
  • Para saber mais sobre o serviço gerenciado, é possível agendar uma demo ou consultar a documentação
  • As orientações para contribuição estão em CONTRIBUTING.md, e perguntas podem ser feitas no Discord

1 comentários

 
GN⁺ 2024-11-19
Opiniões no Hacker News
  • Além do PageRank, há algumas métricas de centralidade interessantes que podem influenciar RAG em dados estruturados
    Entre elas, a Triangle Centrality calcula a centralidade contando os triângulos ao redor de um nó, com base na ideia de que triângulos fecham relações de forma forte, enquanto conexões abertas tiram peso do centro e diluem a centralidade
    https://arxiv.org/abs/2105.00110
    O artigo diz que ela é mais eficiente do que outras centralidades como PageRank, mas em um estudo usando GraphBLAS, a TC foi mais lenta que nossa implementação esparsa de PageRank em vários grafos esparsos até a escala de 1,8 bilhão de arestas
    Ainda assim, parece que a TC escala melhor conforme o grafo fica maior, e é bem possível que seja mais eficiente na faixa de trilhões de arestas
    https://fossies.org/linux/SuiteSparse/GraphBLAS/Doc/The_Grap...

    • Aqui estamos falando de milhões de nós/arestas, então eficiência não é um grande problema
      De todo modo, a geração da resposta provavelmente terá como gargalo a parte que o LLM analisa
      PageRank é o primeiro passo, mas também quero testar alternativas mais precisas
      Aqui usamos PageRank personalizado, dando pesos iniciais a um conjunto específico de nós, e fico curioso se Triangle Centrality também dá suporte a isso
      Também estamos considerando pesos de arestas, então gostaria de saber se isso também é possível
    • Fico curioso se vocês tentaram Authority Rank como substituto para PageRank
      https://link.springer.com/content/pdf/10.1007/978-3-030-6097...
  • Já trabalhei bastante nessa área e aprendi algumas coisas

    1. Se for possível fazer um pouco de trabalho com LLM no momento da ingestão, apenas a busca lexical baseada em BM25 já produz resultados muito relevantes
    2. Embeddings só funcionam bem quando o tamanho da consulta é aproximadamente da mesma ordem do que é colocado no repositório de embeddings
    3. Fazer o LLM gerar uma resposta hipotética a partir da consulta e usar essa resposta hipotética para busca por embeddings funciona muito bem
      Combinei essas três ideias para criar uma etapa semelhante de decomposição/extração de conhecimento e acoplei a ela um metaprompter para praticamente gerar automaticamente o domínio/tipo de entidade
      LLMs, por padrão, não acertam bem o nível correto de granularidade do conhecimento decomposto
      Um truque é pedir ao LLM que gere um mapa mental em mermaid.js para dividir a entrada em uma árvore hierárquica e, no fim, diga qual nível é a raiz adequada para os nós de conhecimento
      Depois, gero perguntas que podem ser respondidas com o conhecimento dentro desse nó, indexo o texto dessas perguntas e também gero embeddings delas
      Mesmo fazer o pareamento direto da consulta do usuário com essas perguntas usando BM25 puro dá bons resultados, e uma abordagem híbrida é melhor, embora a diferença não seja tão grande
      Se você não usar LLM no momento da consulta, também dá para descer hierarquicamente da raiz para nós mais profundos usando a similaridade de embeddings como função de custo de percurso
    • Já experimentei uma estrutura em árvore parecida no passado e tive bons resultados
      No fim, decidi migrar para grafos como uma generalização da árvore
      Vejo como central a ideia de usar similaridade de embeddings para “percorrer” o grafo, e isso também está sendo integrado ativamente ao FastGraphRAG por meio de pesos de arestas de acordo com a consulta
      É interessante ver várias soluções convergirem para um design parecido
    • Seria bom se você explicasse melhor o que significa “um pouco de trabalho com LLM no momento da ingestão” e qual é o objetivo disso
      A ideia de gerar uma resposta hipotética a partir da consulta e então fazer busca por embeddings com essa resposta é interessante; pretendo adicioná-la à lista de experimentos
    • Fico feliz em ouvir que criar uma resposta hipotética a partir da consulta e usá-la no fluxo de RAG realmente funciona bem
      Agora também fico curioso se gerar a resposta hipotética com um LLM ajustado ao corpus funcionaria ainda melhor
    • Fico curioso se o texto que entra no índice BM25 é dividido em chunks
      Também gostaria de saber se, ao criar a resposta hipotética, vocês fazem o prompt para que a resposta corresponda ao “tamanho do chunk”
  • Usar PageRank para obter uma centralidade melhor parece bom, mas ainda não resolve a falha talvez insolúvel do RAG, ou seja, por que o RAG é fundamentalmente difícil de fazer funcionar
    O motivo pelo qual todos os DBs de RAG têm desempenho abaixo do esperado é que o RAG, fundamentalmente, não encontra as relações entre palavras necessárias para localizar as informações que o usuário quer
    Pode soar estranho, e dá para pensar que o mecanismo de “atenção” original deveria ser bom nesse tipo de coisa, mas na prática ele não é suficiente
    Por exemplo, suponha que um texto diga que uma pessoa chamada “Sharon” participou de várias conferências de físico-química, mas não declare explicitamente sua profissão
    Se você procurar “qual é a profissão de Sharon?”, é bem provável que quase todas as abordagens de RAG não consigam conectar “profissão”, participação em conferências e o tipo de conferência para inferir “química”
    Esse tipo de erro está espalhado por vários tipos de informação ao recuperar informações com RAG
    No fim, soluções como a acima parecem reinventar, em mais etapas, outros métodos de consulta como SQL e PageRank, e nesse ponto a vetorização faz pouco sentido

    • Acho que essa inferência não é o papel do LLM?
      O componente de RAG só precisa encontrar, em um grande conjunto de dados, os textos relacionados a Sharon e passar tudo como contexto para o LLM
    • Pelo contrário, esse exemplo é exatamente o ponto central desta abordagem
      Se você olhar o artigo HippoRAG citado no post original, o exemplo motivador é quase idêntico, e a avaliação também é voltada em grande parte a esse tipo de pergunta e resposta multi-hop
    • Usar um grafo de conhecimento não parece tornar isso impossível
      Basta obter a entidade Sharon e receber, como contexto adicional, os nós e arestas próximos de Sharon
      Depois disso é papel do LLM e, se a profissão não estiver no contexto fornecido, ele deve informar: “não é possível encontrar a profissão de Sharon no contexto fornecido”
  • Achei interessante, então me cadastrei e subi alguns documentos PDF no dashboard
    O caso de uso é analisar documentos de compliance relacionados à manufatura em uma startup de IA; para que isso seja útil para nós, precisamos entender até que escala funciona e qual é o modelo de custos
    Temos cerca de 300 mil PDFs por cliente, e esperamos que aproximadamente 10% do conjunto de documentos mude a cada mês
    Qualquer sistema GraphRAG precisa processar documentos em grande escala; podemos usar S3 como mecanismo de ingestão, mas precisamos saber o custo e o tempo de processamento até o sistema ficar utilizável nos seguintes momentos:

    1. carga inicial
    2. atualizações periódicas — por exemplo, como o sistema remove dados
    • Acho que consigo ajudar
      Gostaria de conversar com mais detalhes, então entre em contato em antonio [at] circlemind.co
  • Interessante; fico me perguntando quão grande precisa ser um corpus de texto específico de domínio para obter um grafo de conhecimento útil
    O Aider há tempos aplica PageRank ao grafo de chamadas de repositórios de código
    Qualquer código não trivial tem bastante estrutura de grafo para sustentar o PageRank, então isso funciona muito bem para encontrar o contexto mais relevante dentro do projeto relacionado à tarefa atual
    https://aider.chat/docs/repomap.html#optimizing-the-map

    • Já testei desde romances curtos até documentos completos com milhões de tokens, e ambos parecem criar grafos interessantes
      Quero ouvir feedback quando mais pessoas começarem a usar
    • Uso bastante o Aider, mas nunca consegui fazer ele criar um repo map com sucesso, seja em codebases Python, JS ou TS
      Fico me perguntando se há planos para permitir forçar a geração de um repo map e inspecioná-lo
  • Legal
    Fico curioso sobre como o grafo é armazenado e consultado
    Estou familiarizado com bancos de dados de grafos, mas isso não parece ser uma dependência
    Também queria saber se vocês tentaram usar o modelo sciphi triplex para extração
    Quando fiz extração no passado, extrair o mesmo chunk várias vezes em sequência produzia resultados inconsistentes

    • Atualmente, o grafo é armazenado com python-igraph
      A codebase foi projetada para integrar facilmente qualquer banco de grafos escrevendo um wrapper leve, e pretendemos oferecer suporte a coisas como neo4j em um futuro próximo
      Ainda não testamos o triplex, porque o gpt4o-mini tem sido rápido e preciso o bastante por enquanto
      Usamos o gpt4o-mini não só para extração de entidades e relações, mas também para geração de descrições e resolução de conflitos
      Com fine-tuning, os resultados com certeza ficariam melhores
      A consulta ao grafo funciona encontrando um conjunto inicial de nós relevantes para uma determinada consulta e, depois, executando PageRank personalizado a partir desses nós para encontrar outros trechos relacionados
      No momento, escolhemos os nós iniciais por busca semântica tanto da consulta inteira quanto das entidades extraídas dela, mas também temos alguns recursos adicionais interessantes planejados para esse método
  • Boa ideia
    Pessoalmente, acho que a recuperação de informação tradicional é o caminho para RAG
    Busca vetorial é boa, mas lenta e cara, e as pessoas tendem a usá-la como pó mágico
    Funciona bem para dados não estruturados, mas não necessariamente se encaixa tão bem em dados estruturados
    A menos que seja muito bem ajustada, a busca vetorial também não é muito melhor do que uma consulta tradicional bem ajustada
    Já vi práticas de transformar dados estruturados em dados não estruturados para então fazer busca vetorial ou engenharia de prompt, e no geral isso parece um pouco de trás para frente
    Até funciona em alguma medida, mas provavelmente há uma forma mais inteligente de obter o mesmo resultado
    A essência do Graph RAG é aproveitar a estrutura dos dados
    Não importa muito se isso é um join SQL ou uma consulta em banco de grafos
    Também haverá valor em ensinar o LLM a consultar ou a fazer interface com APIs existentes de busca/consulta
    Um ranqueamento ruim pode ser compensado com uma janela de contexto maior, trazendo centenas ou mais resultados com múltiplas consultas
    Escalar desse jeito deve ser muito mais rápido e barato do que busca vetorial

  • Parece bom, mas já me queimei com outras camadas de abstração como o LangChain, então me preocupo com simplificação excessiva
    Fico curioso sobre como vocês planejam evitar repetir os mesmos erros

  • Fico curioso se há pontuações de métricas de avaliação para recuperação e geração
    Por exemplo, em datasets como KILT ou NQ
    Datasets de benchmark não são tudo, mas mostrar pontuações razoavelmente boas e tempos de inferência ajudaria muito a defender o framework ou a fazer engenheiros escolhê-lo
    Como engenheiro freelancer de processamento de linguagem natural, já criei muitos pipelines RAG, e pretendo testar este trabalho diretamente

  • Estou criando um chatbot de Q&A no momento e tenho dificuldade para lidar com o seguinte cenário
    Quando o usuário pergunta “o que você quis dizer naquela frase anterior que acabou de falar?”, fico me perguntando como este framework conseguiria recuperar o subconjunto pequeno e correto de conhecimento bruto e integrá-lo ao LLM para gerar uma resposta relevante
    Foi difícil resolver esse problema sem depender de frameworks externos
    https://www.reddit.com/r/LocalLLaMA/comments/1gtzdid/d_optim...
    Quero entender como este framework pode resolver esse problema e simplificar o processo

    • Depois de vários experimentos, a única coisa que funcionou bem em aplicações no estilo chat foi passar as últimas 4 a 5 mensagens e, se possível, todo o histórico da conversa, e então pedir ao LLM para resumir a pergunta dentro do contexto da conversa
      Sem isso, falhava com frequência quando o usuário fazia perguntas como “explique melhor o item 2” ou “dê um exemplo detalhado do que está acima”
      A implementação atual mantém 3 índices e, depois de fornecer a consulta e as mensagens anteriores, pede ao LLM para decompor nos seguintes itens:
      solicitação completa, pergunta otimizada para BM25, palavras-chave, pergunta otimizada para busca semântica
      Depois disso, executa RAG e reranking, e passa os N principais trechos junto com a solicitação completa para uma segunda chamada ao LLM
    • Se o usuário fizer esse tipo de pergunta, o agente não deve chamar RAG; deve responder apenas com o histórico da conversa
      É preciso focar na etapa de orquestração
      Procure por agentes ReAct; dá para criar isso com LangGraph ou Bedrock Agents
    • Fico curioso se você já tentou fazer o LLM decidir se deve usar busca de conhecimento por meio do uso de ferramentas ou consulta direta