Download app/llama_client.py from Cnass/mtapi: direct link, hf CLI and curl.
- Browser
- Download file 2.34 kB
-
https://huggingface.co/spaces/Cnass/mtapi/resolve/main/app/llama_client.py
- Command line
-
hf download hf://spaces/Cnass/mtapi/app/llama_client.py
-
curl -L -o llama_client.py https://huggingface.co/spaces/Cnass/mtapi/resolve/main/app/llama_client.py
2.34 kB
| """Thin async client for the internal llama-server instance. | |
| llama-server is started with --parallel N --cont-batching (see entrypoint.sh), | |
| which makes it batch multiple in-flight requests' forward passes together | |
| instead of running them one at a time. This is where the actual CPU | |
| efficiency gain for many short strings comes from: we just need to keep | |
| enough requests in flight concurrently, and llama.cpp does the batching. | |
| """ | |
| import asyncio | |
| import httpx | |
| from . import config | |
| _client: httpx.AsyncClient | None = None | |
| # Bounds how many requests we hand to llama-server at once. Slightly above | |
| # PARALLEL_SLOTS would over-queue on the server side instead of here; we | |
| # keep it equal so backpressure is visible to callers via queueing time. | |
| _semaphore = asyncio.Semaphore(config.PARALLEL_SLOTS) | |
| def get_client() -> httpx.AsyncClient: | |
| global _client | |
| if _client is None: | |
| _client = httpx.AsyncClient( | |
| base_url=config.LLAMA_SERVER_URL, | |
| timeout=httpx.Timeout(config.REQUEST_TIMEOUT_SECONDS), | |
| ) | |
| return _client | |
| async def aclose() -> None: | |
| global _client | |
| if _client is not None: | |
| await _client.aclose() | |
| _client = None | |
| class LlamaServerError(RuntimeError): | |
| pass | |
| async def chat_complete( | |
| messages: list[dict[str, str]], max_tokens: int | None = None | |
| ) -> str: | |
| client = get_client() | |
| payload = { | |
| "messages": messages, | |
| "temperature": config.TEMPERATURE, | |
| "top_p": config.TOP_P, | |
| "top_k": config.TOP_K, | |
| "repeat_penalty": config.REPEAT_PENALTY, | |
| "max_tokens": max_tokens or config.MAX_TOKENS, | |
| "stream": False, | |
| } | |
| async with _semaphore: | |
| try: | |
| resp = await client.post("/v1/chat/completions", json=payload) | |
| resp.raise_for_status() | |
| except httpx.HTTPError as exc: | |
| raise LlamaServerError(str(exc)) from exc | |
| data = resp.json() | |
| try: | |
| return data["choices"][0]["message"]["content"].strip() | |
| except (KeyError, IndexError) as exc: | |
| raise LlamaServerError(f"Unexpected llama-server response: {data}") from exc | |
| async def health() -> bool: | |
| client = get_client() | |
| try: | |
| resp = await client.get("/health", timeout=5.0) | |
| return resp.status_code == 200 | |
| except httpx.HTTPError: | |
| return False | |