Otimizar a velocidade de inferência com o armazenamento em cache de prefixos

O armazenamento em cache de prefixos é um recurso que reduz o tempo de inferência ao armazenar e reutilizar o estado intermediário do LLM de processamento de uma parte de prefixo de comando compartilhada e recorrente. Para ativar o armazenamento em cache de prefixos, basta separar o prefixo estático do sufixo dinâmico na solicitação de API.

No momento, o armazenamento em cache de prefixo só aceita entradas de texto. Portanto, não use esse recurso se você estiver fornecendo uma imagem no comando.

Há duas abordagens para implementar o armazenamento em cache de prefixos: implícita ou explícita:

Usar o armazenamento em cache de prefixo de forma implícita

Para ativar o armazenamento em cache de prefixo, adicione a parte compartilhada do comando ao campo promptPrefix, conforme mostrado nos seguintes snippets de código:

Kotlin

val promptPrefix = "Reverse the given sentence: "
val dynamicSuffix = "Hello World"

val result = generativeModel.generateContent(
  generateContentRequest(TextPart(dynamicSuffix)) {
    promptPrefix = PromptPrefix(promptPrefix)
  }
)

Java

String promptPrefix = "Reverse the given sentence: ";
String dynamicSuffix = "Hello World";

GenerateContentResponse response = generativeModelFutures.generateContent(
    new GenerateContentRequest.Builder(new TextPart(dynamicSuffix))
    .setPromptPrefix(new PromptPrefix(promptPrefix))
    .build())
    .get();

No snippet anterior, o dynamicSuffix é transmitido como o conteúdo principal, e o promptPrefix é fornecido separadamente.

Ganhos de performance estimados

Sem armazenamento em cache de prefixo

Com ocorrência em cache de prefixo

(pode ocorrer ausência no cache de prefixo quando o prefixo é usado pela primeira vez)

Pixel 9 com comando de prefixo fixo de 300 tokens e sufixo dinâmico de 50 tokens

0,82 segundo

0,45 segundo

Pixel 9 com um prefixo fixo de 1.000 tokens e um comando de sufixo dinâmico de 100 tokens

2,11 segundos

0,5 segundo

Considerações sobre armazenamento

Com o armazenamento em cache de prefixo implícito, os arquivos de cache são salvos no armazenamento privado do aplicativo cliente, o que aumenta o uso do armazenamento do app. Os arquivos de cache criptografados e os metadados associados, incluindo o texto do prefixo original, são armazenados. Lembre-se das seguintes considerações de armazenamento:

  • O número de caches é gerenciado por um mecanismo LRU (Least Recently Used). Os caches menos usados são excluídos automaticamente quando excedem o valor total máximo de cache.
  • Os tamanhos do cache de comandos dependem do comprimento do prefixo.
  • Para limpar todos os caches criados com o armazenamento em cache de prefixo, use o método generativeMode.clearImplicitCaches().

Usar o gerenciamento explícito de cache

O acesso direto ao modelo inclui métodos explícitos de gerenciamento de cache para dar aos desenvolvedores um controle mais preciso sobre como os caches são criados, pesquisados, usados e removidos. Essas operações manuais são executadas de forma independente do processamento automatizado de cache do sistema.

Este exemplo ilustra como inicializar o gerenciamento de cache explícito e realizar inferências:

Kotlin

val cacheName = "my_cache"
val promptPrefix = "Reverse the given sentence: "
val dynamicSuffix = "Hello World"

// Create a cache
val cacheRequest = createCachedContextRequest(cacheName, PromptPrefix(promptPrefix))
val cache = generativeModel.caches.create(cacheRequest)

// Run inference with the cache
val response = generativeModel.generateContent(
  generateContentRequest(TextPart(dynamicSuffix)) {
    cachedContextName = cache.name
  }
)

Java

String cacheName = "my_cache";
String promptPrefix = "Reverse the given sentence: ";
String dynamicSuffix = "Hello World";

// Create a cache
CachedContext cache = cachesFutures.create(
  new CreateCachedContextRequest.Builder(cacheName, new PromptPrefix(promptPrefix))
  .build())
  .get();

// Run inference with the cache
GenerateContentResponse response = generativeModelFutures.generateContent(
  new GenerateContentRequest.Builder(new TextPart(dynamicSuffix))
  .setCachedContextName(cache.getName())
  .build())
  .get();

Este exemplo demonstra como consultar, recuperar e excluir caches gerenciados explicitamente usando generativeModel.caches:

Kotlin

val cacheName = "my_cache"

// Query pre-created caches
for (cache in generativeModel.caches.list()) {
  // Do something with cache
}

// Get specific cache
val cache = generativeModel.caches.get(cacheName)

// Delete a pre-created cache
generativeModel.caches.delete(cacheName)

Java

String cacheName = "my_cache";

// Query pre-created caches
for (PrefixCache cache : cachesFutures.list().get()) {
  // Do something with cache
}

// Get specific cache
PrefixCache cache = cachesFutures.get(cacheName).get();

// Delete a pre-created cache
cachesFutures.delete(cacheName);