Fragmentar documentos grandes para soluções de pesquisa vetorial no Azure AI Search
Particionar documentos grandes em partes menores pode ajudá-lo a ficar abaixo dos limites máximos de entrada de token dos modelos de incorporação. Por exemplo, o comprimento máximo do texto de entrada para o modelo de texto-embedding-ada-002 do Azure OpenAI é de 8.191 tokens. Dado que cada token tem cerca de quatro caracteres de texto para modelos OpenAI comuns, este limite máximo é equivalente a cerca de 6.000 palavras de texto. Se você estiver usando esses modelos para gerar incorporações, é fundamental que o texto de entrada permaneça abaixo do limite. Particionar seu conteúdo em partes garante que seus dados possam ser processados pelos modelos de incorporação e que você não perca informações devido ao truncamento.
Recomendamos vetorização integrada para fragmentação e incorporação de dados internos. A vetorização integrada depende de indexadores, conjuntos de habilidades, a habilidade Divisão de texto e uma habilidade de incorporação como a habilidade de incorporação do Azure OpenAI. Se você não puder usar a vetorização integrada, este artigo descreve algumas abordagens para fragmentar seu conteúdo.
Técnicas comuns de fragmentação
A fragmentação só é necessária se os documentos de origem forem muito grandes para o tamanho máximo de entrada imposto pelos modelos.
Aqui estão algumas técnicas comuns de fragmentação, começando com o método mais utilizado:
Blocos de tamanho fixo: Defina um tamanho fixo que seja suficiente para parágrafos semanticamente significativos (por exemplo, 200 palavras) e permita alguma sobreposição (por exemplo, 10-15% do conteúdo) pode produzir bons blocos como entrada para incorporar geradores vetoriais.
Blocos de tamanho variável com base no conteúdo: particione seus dados com base em características de conteúdo, como sinais de pontuação de fim de frase, marcadores de fim de linha ou usando recursos nas bibliotecas de Processamento de Linguagem Natural (NLP). A estrutura da linguagem Markdown também pode ser usada para dividir os dados.
Personalize ou itere sobre uma das técnicas acima. Por exemplo, ao lidar com documentos grandes, você pode usar partes de tamanho variável, mas também acrescentar o título do documento a partes do meio do documento para evitar perda de contexto.
Considerações sobre sobreposição de conteúdo
Quando você divide dados, a sobreposição de uma pequena quantidade de texto entre partes pode ajudar a preservar o contexto. Recomendamos começar com uma sobreposição de aproximadamente 10%. Por exemplo, dado um tamanho de bloco fixo de 256 tokens, você começaria a testar com uma sobreposição de 25 tokens. A quantidade real de sobreposição varia dependendo do tipo de dados e do caso de uso específico, mas descobrimos que 10-15% funciona para muitos cenários.
Fatores para fragmentar dados
Quando se trata de fragmentar dados, pense nestes fatores:
Forma e densidade dos seus documentos. Se você precisar de texto ou passagens intactas, partes maiores e partes variáveis que preservam a estrutura da frase podem produzir melhores resultados.
Consultas do usuário: partes maiores e estratégias sobrepostas ajudam a preservar a riqueza semântica e de contexto para consultas direcionadas a informações específicas.
Os modelos de linguagem grande (LLM) têm diretrizes de desempenho para o tamanho do bloco. Você precisa definir um tamanho de bloco que funcione melhor para todos os modelos que você está usando. Por exemplo, se você usar modelos para sumarização e incorporações, escolha um tamanho de bloco ideal que funcione para ambos.
Como a fragmentação se encaixa no fluxo de trabalho
Se você tiver documentos grandes, deverá inserir uma etapa de fragmentação em fluxos de trabalho de indexação e consulta que divida texto grande. Ao usar vetorização integrada, uma estratégia de fragmentação padrão usando a habilidade Divisão de texto é aplicada. Você também pode aplicar uma estratégia de fragmentação personalizada usando uma habilidade personalizada. Algumas bibliotecas que fornecem fragmentação incluem:
A maioria das bibliotecas fornece técnicas comuns de fragmentação para tamanho fixo, tamanho variável ou uma combinação. Você também pode especificar uma sobreposição que duplique uma pequena quantidade de conteúdo em cada parte para preservação de contexto.
Exemplos de fragmentação
Os exemplos a seguir demonstram como as estratégias de fragmentação são aplicadas ao arquivo PDF do e-book Earth at Night da NASA:
Exemplo de habilidade de divisão de texto
A fragmentação de dados integrada através da habilidade Divisão de texto está geralmente disponível.
Esta seção descreve a fragmentação de dados interna usando uma abordagem orientada por habilidades e parâmetros de habilidade de divisão de texto.
Um bloco de anotações de exemplo para este exemplo pode ser encontrado no repositório azure-search-vector-samples .
Configure textSplitMode
para dividir o conteúdo em partes menores:
pages
(padrão). Os chunks são compostos por várias frases.sentences
. Os chunks são constituídos por frases únicas. O que constitui uma "frase" depende da linguagem. Em inglês, a pontuação padrão de terminação de frase, como.
ou!
é usada. A linguagem é controlada pelodefaultLanguageCode
parâmetro.
O pages
parâmetro adiciona parâmetros extras:
maximumPageLength
define o número máximo de caracteres 1 ou tokens 2 em cada bloco. O divisor de texto evita dividir frases, portanto, a contagem real de caracteres depende do conteúdo.pageOverlapLength
Define quantos caracteres do final da página anterior são incluídos no início da página seguinte. Se definido, deve ser inferior a metade do comprimento máximo da página.maximumPagesToTake
Define quantas páginas/partes devem ser retiradas de um documento. O valor padrão é 0, o que significa tirar todas as páginas ou partes do documento.
1 Os caracteres não se alinham com a definição de um token. O número de tokens medido pelo LLM pode ser diferente do tamanho do caractere medido pela habilidade Divisão de texto.
2 A fragmentação de tokens está disponível na pré-visualização de 2024-09-01 e inclui parâmetros extras para especificar um tokenizador e quaisquer tokens que não devam ser divididos durante a fragmentação.
A tabela a seguir mostra como a escolha dos parâmetros afeta a contagem total de blocos do e-book Earth at Night:
textSplitMode |
maximumPageLength |
pageOverlapLength |
Contagem total de pedaços |
---|---|---|---|
pages |
1000 | 0 | 172 |
pages |
1000 | 200 | 216 |
pages |
2000 | 0 | 85 |
pages |
2000 | 500 | 113 |
pages |
5000 | 0 | 34 |
pages |
5000 | 500 | 38 |
sentences |
N/A | N/A | 13361 |
Usando um textSplitMode
dos pages
resultados na maioria das partes com contagens totais de caracteres próximas a maximumPageLength
. A contagem de caracteres do bloco varia devido a diferenças sobre onde os limites da frase estão dentro do bloco. O comprimento do token do bloco varia devido a diferenças no conteúdo do bloco.
Os histogramas a seguir mostram como a distribuição do comprimento do caractere do bloco se compara ao comprimento do token do bloco para gpt-35-turbo ao usar um textSplitMode
e-book de pages
, a maximumPageLength
de 2000 e um pageOverlapLength
de 500 no e-book Earth at Night:
Usando um textSplitMode
dos sentences
resultados em um grande número de partes que consistem em frases individuais. Esses pedaços são significativamente menores do que aqueles produzidos pela pages
, e a contagem de tokens dos pedaços corresponde mais de perto às contagens de caracteres.
Os histogramas a seguir mostram como a distribuição do comprimento do caractere do bloco se compara ao comprimento do token do bloco para gpt-35-turbo ao usar um textSplitMode
e-book do sentences
Earth at Night:
A escolha ideal de parâmetros depende de como os blocos serão usados. Para a maioria dos aplicativos, é recomendável começar com os seguintes parâmetros padrão:
textSplitMode |
maximumPageLength |
pageOverlapLength |
---|---|---|
pages |
2000 | 500 |
Exemplo de fragmentação de dados LangChain
LangChain fornece carregadores de documentos e divisores de texto. Este exemplo mostra como carregar um PDF, obter contagens de tokens e configurar um divisor de texto. Obter contagens de tokens ajuda você a tomar uma decisão informada sobre o dimensionamento de blocos.
Um bloco de anotações de exemplo para este exemplo pode ser encontrado no repositório azure-search-vector-samples .
from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader("./data/earth_at_night_508.pdf")
pages = loader.load()
print(len(pages))
A saída indica 200 documentos ou páginas no PDF.
Para obter uma contagem de tokens estimada para essas páginas, use o TikToken.
import tiktoken
tokenizer = tiktoken.get_encoding('cl100k_base')
def tiktoken_len(text):
tokens = tokenizer.encode(
text,
disallowed_special=()
)
return len(tokens)
tiktoken.encoding_for_model('gpt-3.5-turbo')
# create the length function
token_counts = []
for page in pages:
token_counts.append(tiktoken_len(page.page_content))
min_token_count = min(token_counts)
avg_token_count = int(sum(token_counts) / len(token_counts))
max_token_count = max(token_counts)
# print token counts
print(f"Min: {min_token_count}")
print(f"Avg: {avg_token_count}")
print(f"Max: {max_token_count}")
A saída indica que nenhuma página tem zero tokens, o comprimento médio do token por página é de 189 tokens e a contagem máxima de tokens de qualquer página é de 1.583.
Saber o tamanho médio e máximo do token lhe dá informações sobre como definir o tamanho do bloco. Embora você possa usar a recomendação padrão de 2000 caracteres com uma sobreposição de 500 caracteres, neste caso faz sentido ir mais baixo, dadas as contagens de tokens do documento de exemplo. Na verdade, definir um valor de sobreposição muito grande pode resultar em nenhuma sobreposição aparecendo.
from langchain.text_splitter import RecursiveCharacterTextSplitter
# split documents into text and embeddings
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
length_function=len,
is_separator_regex=False
)
chunks = text_splitter.split_documents(pages)
print(chunks[20])
print(chunks[21])
A saída para dois blocos consecutivos mostra o texto do primeiro bloco sobreposto ao segundo bloco. A saída é levemente editada para facilitar a leitura.
'x Earth at NightForeword\nNASA’s Earth at Night explores the brilliance of our planet when it is in darkness. \n It is a compilation of stories depicting the interactions between science and \nwonder, and I am pleased to share this visually stunning and captivating exploration of \nour home planet.\nFrom space, our Earth looks tranquil. The blue ethereal vastness of the oceans \nharmoniously shares the space with verdant green land—an undercurrent of gentle-ness and solitude. But spending time gazing at the images presented in this book, our home planet at night instantly reveals a different reality. Beautiful, filled with glow-ing communities, natural wonders, and striking illumination, our world is bustling with activity and life.**\nDarkness is not void of illumination. It is the contrast, the area between light and'** metadata={'source': './data/earth_at_night_508.pdf', 'page': 9}
'**Darkness is not void of illumination. It is the contrast, the area between light and **\ndark, that is often the most illustrative. Darkness reminds me of where I came from and where I am now—from a small town in the mountains, to the unique vantage point of the Nation’s capital. Darkness is where dreamers and learners of all ages peer into the universe and think of questions about themselves and their space in the cosmos. Light is where they work, where they gather, and take time together.\nNASA’s spacefaring satellites have compiled an unprecedented record of our \nEarth, and its luminescence in darkness, to captivate and spark curiosity. These missions see the contrast between dark and light through the lenses of scientific instruments. Our home planet is full of complex and dynamic cycles and processes. These soaring observers show us new ways to discern the nuances of light created by natural and human-made sources, such as auroras, wildfires, cities, phytoplankton, and volcanoes.' metadata={'source': './data/earth_at_night_508.pdf', 'page': 9}
Habilidade personalizada
Um exemplo de geração de fragmentação e incorporação de tamanho fixo demonstra a geração de fragmentação e incorporação de vetores usando modelos de incorporação do Azure OpenAI . Este exemplo usa uma habilidade personalizada do Azure AI Search no repositório Power Skills para envolver a etapa de fragmentação.