Spaces:
Running on Zero
Running on Zero
pareshmishra
Optimize LLM latency by disabling chain-of-thought generation for direct JSON extraction
bcb01d9 Download src/nvidia_client.py from pareshmishra/document-Intelligence-OCR: direct link, hf CLI and curl.
- Browser
- Download file 5.14 kB
-
https://huggingface.co/spaces/pareshmishra/document-Intelligence-OCR/resolve/main/src/nvidia_client.py
- Command line
-
hf download hf://spaces/pareshmishra/document-Intelligence-OCR/src/nvidia_client.py
-
curl -L -o nvidia_client.py https://huggingface.co/spaces/pareshmishra/document-Intelligence-OCR/resolve/main/src/nvidia_client.py
5.14 kB
| import os | |
| import json | |
| import re | |
| import time | |
| import logging | |
| from typing import Dict, Any, Optional | |
| from openai import OpenAI, APIError, AuthenticationError, RateLimitError | |
| from .config import settings | |
| logger = logging.getLogger("document_intelligence.nvidia") | |
| class NVIDIAClient: | |
| """Client for invoking NVIDIA LLM inference endpoints via OpenAI compatible API.""" | |
| def __init__( | |
| self, | |
| api_key: Optional[str] = None, | |
| base_url: Optional[str] = None, | |
| model: Optional[str] = None, | |
| ): | |
| self.api_key = api_key or settings.NVIDIA_API_KEY | |
| self.base_url = base_url or settings.NVIDIA_BASE_URL | |
| self.model = model or settings.NVIDIA_MODEL | |
| self._client: Optional[OpenAI] = None | |
| def _get_client(self) -> OpenAI: | |
| """Lazily initialize and return the OpenAI client configured for NVIDIA.""" | |
| if not self.api_key: | |
| raise ValueError( | |
| "NVIDIA_API_KEY is not set. Please provide a valid NVIDIA API Key via environment variables." | |
| ) | |
| if self._client is None: | |
| self._client = OpenAI( | |
| base_url=self.base_url, | |
| api_key=self.api_key, | |
| timeout=60.0 | |
| ) | |
| return self._client | |
| def generate_document_intelligence( | |
| self, | |
| system_prompt: str, | |
| user_prompt: str, | |
| temperature: float = 0.2, | |
| top_p: float = 0.95, | |
| max_tokens: int = 4096, | |
| ) -> Dict[str, Any]: | |
| """ | |
| Send document extraction text and prompt to NVIDIA LLM. | |
| Returns parsed JSON dict, reasoning content (if any), and latency. | |
| """ | |
| client = self._get_client() | |
| start_time = time.time() | |
| messages = [ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": user_prompt}, | |
| ] | |
| logger.info( | |
| "Invoking NVIDIA model '%s' at '%s'", self.model, self.base_url | |
| ) | |
| try: | |
| extra_body = {} | |
| if "nemotron" in self.model.lower(): | |
| extra_body["chat_template_kwargs"] = {"enable_thinking": False} | |
| completion = client.chat.completions.create( | |
| model=self.model, | |
| messages=messages, | |
| temperature=temperature, | |
| top_p=top_p, | |
| max_tokens=min(max_tokens, 2048), | |
| extra_body=extra_body if extra_body else None, | |
| stream=False, | |
| ) | |
| raw_choice = completion.choices[0] | |
| raw_content = raw_choice.message.content or "" | |
| reasoning = getattr(raw_choice.message, "reasoning_content", None) | |
| latency = time.time() - start_time | |
| logger.info("NVIDIA model invocation completed in %.3f seconds", latency) | |
| parsed_json = self._extract_json(raw_content) | |
| return { | |
| "parsed_data": parsed_json, | |
| "raw_text": raw_content, | |
| "reasoning": reasoning, | |
| "latency_seconds": round(latency, 4), | |
| "model": self.model, | |
| } | |
| except AuthenticationError as e: | |
| logger.error("NVIDIA Authentication failed. Verify NVIDIA_API_KEY.") | |
| raise ValueError("Authentication with NVIDIA API failed. Please check your NVIDIA_API_KEY.") from e | |
| except RateLimitError as e: | |
| logger.error("NVIDIA Rate Limit exceeded: %s", e) | |
| raise RuntimeError("NVIDIA API rate limit exceeded. Please retry shortly.") from e | |
| except APIError as e: | |
| logger.error("NVIDIA API error: %s", e) | |
| raise RuntimeError(f"NVIDIA API error: {e.message}") from e | |
| except Exception as e: | |
| logger.error("Unexpected error during NVIDIA model call: %s", e) | |
| raise RuntimeError(f"Failed to communicate with NVIDIA LLM: {str(e)}") from e | |
| def _extract_json(self, text: str) -> Dict[str, Any]: | |
| """Extract and clean valid JSON from model response text.""" | |
| cleaned = text.strip() | |
| # Handle markdown code fences ```json ... ``` | |
| json_match = re.search(r"```(?:json)?\s*([\s\S]*?)\s*```", cleaned) | |
| if json_match: | |
| candidate = json_match.group(1).strip() | |
| try: | |
| return json.loads(candidate) | |
| except json.JSONDecodeError: | |
| pass | |
| # Handle raw json string | |
| try: | |
| return json.loads(cleaned) | |
| except json.JSONDecodeError: | |
| pass | |
| # Try to find the first '{' and last '}' | |
| start_idx = cleaned.find("{") | |
| end_idx = cleaned.rfind("}") | |
| if start_idx != -1 and end_idx != -1 and end_idx > start_idx: | |
| sub = cleaned[start_idx : end_idx + 1] | |
| try: | |
| return json.loads(sub) | |
| except json.JSONDecodeError as e: | |
| logger.error("Failed to parse JSON substring: %s", e) | |
| raise ValueError( | |
| f"Could not parse valid JSON from NVIDIA model output: {cleaned[:200]}..." | |
| ) | |
| # Global instance | |
| nvidia_client = NVIDIAClient() | |