Ottimizzare la velocità di inferenza con la memorizzazione nella cache dei prefissi

La memorizzazione nella cache dei prefissi è una funzionalità che riduce il tempo di inferenza memorizzando e riutilizzando lo stato LLM intermedio dell'elaborazione di una parte di prefisso del prompt condivisa e ricorrente. Per abilitare la memorizzazione nella cache dei prefissi, devi solo separare il prefisso statico dal suffisso dinamico nella richiesta API.

Al momento, la memorizzazione nella cache del prefisso supporta solo l'input di testo, quindi non dovresti utilizzare questa funzionalità se fornisci un'immagine nel prompt.

Esistono due approcci per implementare la memorizzazione nella cache del prefisso: implicito o esplicito:

Utilizza la memorizzazione nella cache dei prefissi in modo implicito

Per attivare la memorizzazione nella cache del prefisso, aggiungi la parte condivisa del prompt al campo promptPrefix, come mostrato nei seguenti snippet di codice:

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();

Nello snippet precedente, dynamicSuffix viene passato come contenuto principale e promptPrefix viene fornito separatamente.

Miglioramenti delle prestazioni stimati

Senza memorizzazione nella cache dei prefissi

Con successo della cache del prefisso

(Il fallimento della cache del prefisso potrebbe verificarsi quando il prefisso viene utilizzato per la prima volta)

Pixel 9 con prompt con prefisso fisso di 300 token e suffisso dinamico di 50 token

0,82 secondi

0,45 secondi

Pixel 9 con un prefisso fisso di 1000 token e un prompt con suffisso dinamico di 100 token

2,11 secondi

0,5 secondi

Considerazioni sullo spazio di archiviazione

Con la memorizzazione nella cache implicita dei prefissi, i file della cache vengono salvati nello spazio di archiviazione privato dell'applicazione client, il che aumenta l'utilizzo dello spazio di archiviazione dell'app. I file di cache criptati e i relativi metadati associati, incluso il testo del prefisso originale, vengono archiviati. Tieni presente le seguenti considerazioni sullo spazio di archiviazione:

  • Il numero di cache è gestito da un meccanismo LRU (Least Recently Used). Le cache meno utilizzate vengono eliminate automaticamente quando viene superato l'importo totale massimo della cache.
  • Le dimensioni della cache dei prompt dipendono dalla lunghezza del prefisso.
  • Per cancellare tutte le cache create dalla memorizzazione nella cache del prefisso, utilizza il metodo generativeMode.clearImplicitCaches().

Utilizza la gestione esplicita della cache

L'accesso diretto al modello include metodi espliciti di gestione della cache per offrire agli sviluppatori un controllo più preciso su come vengono create, cercate, utilizzate e rimosse le cache. Queste operazioni manuali vengono eseguite indipendentemente dalla gestione automatica della cache del sistema.

Questo esempio illustra come inizializzare la gestione esplicita della cache ed eseguire l'inferenza:

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();

Questo esempio mostra come eseguire query, recuperare ed eliminare le cache gestite in modo esplicito utilizzando 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);