runbook : contournement direct NVIDIA NIM/OpenRouter pour onedrive_vec
This commit is contained in:
@@ -0,0 +1,127 @@
|
|||||||
|
# nyora-notes-tt -- contournement direct NVIDIA NIM/OpenRouter pour onedrive_vec
|
||||||
|
|
||||||
|
**Instance auteur** : hermes-tt (Claude, session nyora-notes-tt)
|
||||||
|
**Date** : 2026-08-05
|
||||||
|
**Tags** : nyora-notes-tt, bifrost, embeddings, nvidia-nim, openrouter
|
||||||
|
**Statut** : valide, backfill en cours
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Probleme
|
||||||
|
|
||||||
|
Le quota gratuit Google (`embed_content_free_tier_requests`, 1000/j sur
|
||||||
|
`gemini-embedding-001`) etait epuise, cassant a la fois le backfill embeddings
|
||||||
|
et la recherche vectorielle en temps reel de `search_onedrive_archive`. Le fix
|
||||||
|
de rotation multi-cles Bifrost (voir `common/bifrost-google-provider-key-rotation.md`)
|
||||||
|
ne resout rien : les 3 cles Google partagent le meme pool de quota.
|
||||||
|
|
||||||
|
Tentative de bascule vers NVIDIA NIM et OpenRouter (tous deux gratuits, comptes
|
||||||
|
crees le 05/08) **via Bifrost** : echec dans les deux cas, en 404. Confirme comme
|
||||||
|
bugs Bifrost upstream, pas une erreur de config :
|
||||||
|
- NVIDIA NIM : issue GitHub maximhq/bifrost#2356 (ouverte) -- Bifrost ne transmet
|
||||||
|
pas le header `Authorization` a l'API amont quand le provider est en
|
||||||
|
`custom_provider_config.base_provider_type: openai`.
|
||||||
|
- OpenRouter : erreur cote client HTTP Bifrost ("small read buffer" en lisant
|
||||||
|
les headers de reponse), cause exacte non confirmee dans les issues connues.
|
||||||
|
|
||||||
|
Les deux providers fonctionnent parfaitement en appel DIRECT (sans Bifrost),
|
||||||
|
verifie avec les memes cles.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Solution validee : contournement direct, scope isole a onedrive_vec
|
||||||
|
|
||||||
|
`notes_vec` (mail, alimentee par `pipeline_processor.py`) et `onedrive_vec`
|
||||||
|
(OneDrive, alimentee par `embed_onedrive_docs.py`) sont deux tables
|
||||||
|
**separees**, toutes deux 768d/Google avant ce fix. Decision : ne toucher QUE
|
||||||
|
`onedrive_vec` -- `notes_vec` reste sur Google/Bifrost (768d), fonctionne deja,
|
||||||
|
aucune raison de la casser aujourd'hui.
|
||||||
|
|
||||||
|
**Modele choisi** : `nvidia/llama-nemotron-embed-vl-1b-v2` (2048d), disponible
|
||||||
|
IDENTIQUE (memes poids) sur NVIDIA NIM et sur OpenRouter (OpenRouter route ce
|
||||||
|
modele gratuit directement vers l'infra NVIDIA -- "hosted by one provider").
|
||||||
|
Consequence utile : les deux sources produisent le MEME espace vectoriel, donc
|
||||||
|
un vrai repli (pas deux embeddings incompatibles a ne jamais mixer).
|
||||||
|
|
||||||
|
**Code** (`embed_onedrive_docs.py` et nouvelle fonction `generate_onedrive_embedding`
|
||||||
|
dans `mcp_server.py`, strictement separee de `generate_gemini_embedding` qui
|
||||||
|
reste utilisee par `search_mail_memory`) :
|
||||||
|
|
||||||
|
```python
|
||||||
|
NVIDIA_NIM_API_KEY = os.getenv("NVIDIA_NIM_API_KEY", "")
|
||||||
|
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY", "")
|
||||||
|
EMBEDDING_MODEL = "nvidia/llama-nemotron-embed-vl-1b-v2"
|
||||||
|
EMBEDDING_DIMENSIONS = 2048
|
||||||
|
|
||||||
|
def get_embedding(text):
|
||||||
|
text = text[:8000]
|
||||||
|
if NVIDIA_NIM_API_KEY:
|
||||||
|
try:
|
||||||
|
resp = httpx.post(
|
||||||
|
"https://integrate.api.nvidia.com/v1/embeddings",
|
||||||
|
headers={"Authorization": f"Bearer {NVIDIA_NIM_API_KEY}"},
|
||||||
|
json={"model": EMBEDDING_MODEL, "input": [text], "input_type": "passage"},
|
||||||
|
timeout=30,
|
||||||
|
)
|
||||||
|
resp.raise_for_status()
|
||||||
|
vec = resp.json()["data"][0]["embedding"]
|
||||||
|
if len(vec) == EMBEDDING_DIMENSIONS:
|
||||||
|
return vec
|
||||||
|
except Exception:
|
||||||
|
pass # repli OpenRouter
|
||||||
|
if OPENROUTER_API_KEY:
|
||||||
|
resp = httpx.post(
|
||||||
|
"https://openrouter.ai/api/v1/embeddings",
|
||||||
|
headers={"Authorization": f"Bearer {OPENROUTER_API_KEY}"},
|
||||||
|
json={"model": EMBEDDING_MODEL, "input": text},
|
||||||
|
timeout=30,
|
||||||
|
)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return resp.json()["data"][0]["embedding"]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Piege NVIDIA NIM specifique** : le parametre `input_type` (`"query"` ou
|
||||||
|
`"passage"`) est requis par leurs modeles NV-Embed*, absent chez OpenRouter --
|
||||||
|
mis uniquement sur l'appel NVIDIA direct.
|
||||||
|
|
||||||
|
**Migration schema** : `onedrive_vec` (`vec0`, dimension figee a la creation)
|
||||||
|
recree en 2048d, perte des 1781 vecteurs 768d existants (non recuperables,
|
||||||
|
mauvais espace vectoriel de toute facon) -- backfill relance depuis zero sur
|
||||||
|
6648 documents processed, rythme observe ~1/s (~2h estimees), aucune erreur
|
||||||
|
constatee sur le premier lot.
|
||||||
|
|
||||||
|
**Secrets** : cles dans `/volume1/docker/nyora-notes-tt/.env`
|
||||||
|
(`NVIDIA_NIM_API_KEY`, `OPENROUTER_API_KEY`) -- PAS via Bifrost pour cet usage
|
||||||
|
precis, contournement volontaire tant que #2356 n'est pas corrige upstream.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec nyora-notes-tt python3 -c "
|
||||||
|
import sqlean as sqlite3, sqlite_vec
|
||||||
|
c = sqlite3.connect('/app/nyora-notes-tt.db')
|
||||||
|
c.enable_load_extension(True); sqlite_vec.load(c); c.enable_load_extension(False)
|
||||||
|
print(c.execute('SELECT COUNT(*) FROM onedrive_vec').fetchone()[0])
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reste a faire
|
||||||
|
|
||||||
|
- Laisser le backfill se terminer (~2h, tourne en arriere-plan via
|
||||||
|
`docker exec -d`, resumable si interrompu -- rescanner simplement au
|
||||||
|
redemarrage, la logique "deja embedde" se base sur les rowid presents).
|
||||||
|
- Reevaluer le retour a Bifrost si/quand #2356 est corrige upstream (verifier
|
||||||
|
changelog maximhq/bifrost).
|
||||||
|
- Auto-actualisation OneDrive (point 1) et ingestion mail continue (point 2) :
|
||||||
|
design discute mais pas implemente -- voir prompt de reprise en session
|
||||||
|
suivante.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- Issue Bifrost NVIDIA NIM : https://github.com/maximhq/bifrost/issues/2356
|
||||||
|
- Runbook associe : `common/bifrost-google-provider-key-rotation.md`,
|
||||||
|
`hermes-tt/nyora-notes-tt-3-bugs-05-08-2026.md`
|
||||||
Reference in New Issue
Block a user