Download tests/test_embed.py from CamiloS1111/ragsolver: direct link, hf CLI and curl.
- Browser
- Download file 1.48 kB
-
https://huggingface.co/CamiloS1111/ragsolver/resolve/main/tests/test_embed.py
- Command line
-
hf download hf://CamiloS1111/ragsolver/tests/test_embed.py
-
curl -L -o test_embed.py https://huggingface.co/CamiloS1111/ragsolver/resolve/main/tests/test_embed.py
1.48 kB
| """BUG-6 — la caché de embeddings de consulta (`rag/embed.py::embed_queries`) se | |
| lee y escribe desde varios hilos (`orchestrator/run.py --workers N`); sin lock, | |
| la evicción FIFO podía romper a mitad de iteración con `RuntimeError: dictionary | |
| changed size during iteration`.""" | |
| from __future__ import annotations | |
| from concurrent.futures import ThreadPoolExecutor | |
| from ragsolver.rag import embed as E | |
| def test_embed_queries_is_safe_under_concurrent_access(monkeypatch): | |
| monkeypatch.setattr(E, "_backend", lambda: "llama") | |
| monkeypatch.setattr(E, "_QUERY_CACHE", {}) | |
| monkeypatch.setattr(E, "_QUERY_CACHE_MAX", 8) # fuerza evicciones frecuentes durante el test | |
| def fake_llama_embed(texts, **kw): | |
| return [[float(len(t))] for t in texts] | |
| monkeypatch.setattr(E, "_llama_embed", fake_llama_embed) | |
| def worker(i: int) -> list[float]: | |
| text = f"query {i % 20}" # 20 textos distintos, más de _QUERY_CACHE_MAX: fuerza reuso + evicción | |
| return E.embed_queries([text], model_name="m")[0] | |
| with ThreadPoolExecutor(max_workers=8) as ex: | |
| results = list(ex.map(worker, range(400))) # sin lock, esto suele lanzar RuntimeError antes de terminar | |
| for i, vec in enumerate(results): | |
| expected = float(len(E.QUERY_INSTRUCTION + f"query {i % 20}")) # la clave de caché incluye el prefijo de instrucción | |
| assert vec == [expected], f"worker {i}: se coló el resultado de otra consulta (carrera en la caché)" | |