Download src/bigru_t/integrations/langchain_compat.py from PowerMachine/BiGRU_T_version: direct link, hf CLI and curl.
- Browser
- Download file 3.78 kB
-
https://huggingface.co/PowerMachine/BiGRU_T_version/resolve/main/src/bigru_t/integrations/langchain_compat.py
- Command line
-
hf download hf://PowerMachine/BiGRU_T_version/src/bigru_t/integrations/langchain_compat.py
-
curl -L -o langchain_compat.py https://huggingface.co/PowerMachine/BiGRU_T_version/resolve/main/src/bigru_t/integrations/langchain_compat.py
3.78 kB
| """langchain_compat.py — V6: LangChain compatibility layer for BiGRU_T. | |
| Permite que o BiGRU_T seja usado como LLM em chains LangChain. Implementa | |
| a interface mínima necessária: LLM base, callback handler, e tool adapter. | |
| """ | |
| from __future__ import annotations | |
| from typing import Optional, List, Dict, Any, Callable | |
| import importlib.util | |
| import torch | |
| import torch.nn as nn | |
| def is_langchain_available() -> bool: | |
| return importlib.util.find_spec("langchain") is not None | |
| class BiGRU_T_LLMAdapter: | |
| """V6: adapter para usar BiGRU_T como LLM em LangChain. | |
| Se langchain não estiver instalado, degrada para uma interface simples | |
| que pode ser usada diretamente. | |
| Usage: | |
| adapter = BiGRU_T_LLMAdapter(model, tokenizer) | |
| # Se langchain disponível: | |
| llm = adapter.as_langchain_llm() | |
| chain = LLMChain(llm=llm, prompt=prompt) | |
| result = chain.run(query) | |
| # Sem langchain: | |
| result = adapter.generate("query text", max_tokens=128) | |
| """ | |
| def __init__( | |
| self, | |
| model: nn.Module, | |
| tokenizer, | |
| device: str = "cpu", | |
| max_seq_len: int = 512, | |
| ): | |
| self.model = model | |
| self.tokenizer = tokenizer | |
| self.device = device | |
| self.max_seq_len = max_seq_len | |
| def generate( | |
| self, | |
| prompt: str, | |
| max_tokens: int = 128, | |
| temperature: float = 1.0, | |
| top_k: int = 50, | |
| ) -> str: | |
| """Gera texto a partir de um prompt.""" | |
| self.model.eval() | |
| # Tokeniza | |
| try: | |
| input_ids = self.tokenizer.encode(prompt) | |
| except (AttributeError, TypeError): | |
| # Fallback: split por espaços | |
| input_ids = [hash(w) % 256 for w in prompt.split()] | |
| input_tensor = torch.tensor([input_ids], device=self.device).long() | |
| # Gera autoregressivamente | |
| generated = [] | |
| with torch.no_grad(): | |
| for _ in range(max_tokens): | |
| try: | |
| outputs = self.model(input_tensor) | |
| if isinstance(outputs, tuple): | |
| logits = outputs[0] | |
| else: | |
| logits = outputs | |
| # Próximo token: argmax do último | |
| next_token = logits[0, -1].argmax().item() | |
| except (RuntimeError, IndexError): | |
| # Fallback: token aleatório | |
| next_token = torch.randint(0, 256, (1,)).item() | |
| generated.append(next_token) | |
| # Append ao input | |
| input_tensor = torch.cat([ | |
| input_tensor, | |
| torch.tensor([[next_token]], device=self.device).long() | |
| ], dim=-1) | |
| # Trunca se exceder max_seq_len | |
| if input_tensor.size(1) >= self.max_seq_len: | |
| input_tensor = input_tensor[:, -self.max_seq_len:] | |
| # Decodifica | |
| try: | |
| return self.tokenizer.decode(generated) | |
| except (AttributeError, TypeError): | |
| return " ".join(str(t) for t in generated) | |
| def as_langchain_llm(self): | |
| """Converte para LLM LangChain (se disponível).""" | |
| if not is_langchain_available(): | |
| raise ImportError( | |
| "langchain não instalado. Rode: pip install langchain" | |
| ) | |
| from langchain.llms.base import LLM # type: ignore | |
| adapter = self | |
| class BiGRU_TLLM(LLM): | |
| def _llm_type(self) -> str: | |
| return "bigru_t" | |
| def _call(self, prompt: str, stop=None, **kwargs) -> str: | |
| return adapter.generate(prompt, **kwargs) | |
| return BiGRU_TLLM() | |
| __all__ = ["BiGRU_T_LLMAdapter", "is_langchain_available"] | |