workin on llm_factory
This commit is contained in:
parent
77751ee8ac
commit
e01e424fac
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,36 @@
|
||||||
|
from pathlib import Path
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
import os
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
OPENAI_API_KEY=os.getenv("OPENAI_API_KEY", "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")
|
||||||
|
|
||||||
|
OLLAMA_URL=os.getenv("OLLAMA_URL", "http://host.docker.internal:11434")
|
||||||
|
OLLAMA_LOCAL_URL=os.getenv("OLLAMA_LOCAL_URL", "http://localhost:11434")
|
||||||
|
OLLAMA_MODEL_NAME=os.getenv("OLLAMA_MODEL_NAME", "qwen3-0.6B:latest")
|
||||||
|
OLLAMA_EMB_MODEL_NAME=os.getenv("OLLAMA_EMB_MODEL_NAME", "qwen3-0.6B-emb:latest")
|
||||||
|
|
||||||
|
LANGFUSE_HOST=os.getenv("LANGFUSE_HOST", "http://45.77.119.180")
|
||||||
|
LANGFUSE_PUBLIC_KEY=os.getenv("LANGFUSE_PUBLIC_KEY", "pk-lf-0e6db694-3e95-4dd4-aedf-5a2694267058")
|
||||||
|
LANGFUSE_SECRET_KEY=os.getenv("LANGFUSE_SECRET_KEY", "sk-lf-dbf28bb9-15bb-4d03-a8c3-05caa3e3905f")
|
||||||
|
|
||||||
|
ELASTICSEARCH_URL=os.getenv("ELASTICSEARCH_URL", "http://host.docker.internal:9200")
|
||||||
|
ELASTICSEARCH_LOCAL_URL=os.getenv("ELASTICSEARCH_LOCAL_URL", "http://localhost:9200")
|
||||||
|
ELASTICSEARCH_INDEX=os.getenv("ELASTICSEARCH_INDEX", "avap-docs-test")
|
||||||
|
|
||||||
|
DATABASE_URL=os.getenv("DATABASE_URL", "postgresql://postgres:brunix_pass@host.docker.internal:5432/postgres")
|
||||||
|
|
||||||
|
KUBECONFIG_PATH=os.getenv("KUBECONFIG_PATH", "kubernetes/kubeconfig.yaml")
|
||||||
|
|
||||||
|
HF_TOKEN=os.getenv("HF_TOKEN", "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")
|
||||||
|
HF_EMB_MODEL_NAME=os.getenv("HF_EMB_MODEL_NAME", "Qwen/Qwen3-Embedding-0.6B")
|
||||||
|
|
||||||
|
PROJ_ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
||||||
|
DATA_DIR=PROJ_ROOT / "data"
|
||||||
|
MODELS_DIR=DATA_DIR / "models"
|
||||||
|
RAW_DIR=DATA_DIR / "raw"
|
||||||
|
PROCESSED_DIR=DATA_DIR / "processed"
|
||||||
|
INTERIM_DIR=DATA_DIR / "interim"
|
||||||
|
EXTERNAL_DIR=DATA_DIR / "external"
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from enum import StrEnum
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from langchain_ollama import ChatOllama, OllamaEmbeddings
|
||||||
|
|
||||||
|
|
||||||
|
class Provider(StrEnum):
|
||||||
|
OLLAMA = "ollama"
|
||||||
|
OPENAI = "openai"
|
||||||
|
ANTHROPIC = "anthropic"
|
||||||
|
AWS_BEDROCK = "aws_bedrock"
|
||||||
|
HUGGINGFACE = "huggingface"
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ChatModelConfig:
|
||||||
|
provider: Provider
|
||||||
|
model: str
|
||||||
|
temperature: float = 0.0
|
||||||
|
|
||||||
|
# Ollama
|
||||||
|
ollama_base_url: Optional[str] = None
|
||||||
|
validate_model_on_init: bool = True
|
||||||
|
|
||||||
|
# OpenAI / Anthropic / Azure
|
||||||
|
api_key: Optional[str] = None
|
||||||
|
azure_endpoint: Optional[str] = None
|
||||||
|
azure_deployment: Optional[str] = None
|
||||||
|
api_version: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class EmbeddingsConfig:
|
||||||
|
provider: Provider
|
||||||
|
model: str
|
||||||
|
|
||||||
|
# Ollama
|
||||||
|
ollama_base_url: Optional[str] = None
|
||||||
|
|
||||||
|
# OpenAI / Azure
|
||||||
|
api_key: Optional[str] = None
|
||||||
|
azure_endpoint: Optional[str] = None
|
||||||
|
azure_deployment: Optional[str] = None
|
||||||
|
api_version: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
def build_chat_model(cfg: ChatModelConfig):
|
||||||
|
match cfg.provider:
|
||||||
|
case Provider.OLLAMA:
|
||||||
|
return ChatOllama(
|
||||||
|
model=cfg.model,
|
||||||
|
temperature=cfg.temperature,
|
||||||
|
validate_model_on_init=cfg.validate_model_on_init,
|
||||||
|
base_url=cfg.ollama_base_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.OPENAI:
|
||||||
|
from langchain_openai import ChatOpenAI # pip install langchain-openai
|
||||||
|
|
||||||
|
if not cfg.api_key:
|
||||||
|
raise ValueError("Missing api_key for OpenAI provider.")
|
||||||
|
return ChatOpenAI(
|
||||||
|
model=cfg.model,
|
||||||
|
temperature=cfg.temperature,
|
||||||
|
api_key=cfg.api_key,
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.ANTHROPIC:
|
||||||
|
from langchain_anthropic import ChatAnthropic # pip install langchain-anthropic
|
||||||
|
|
||||||
|
if not cfg.api_key:
|
||||||
|
raise ValueError("Missing api_key for Anthropic provider.")
|
||||||
|
return ChatAnthropic(
|
||||||
|
model=cfg.model,
|
||||||
|
temperature=cfg.temperature,
|
||||||
|
api_key=cfg.api_key,
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.AZURE_OPENAI:
|
||||||
|
from langchain_openai import AzureChatOpenAI # pip install langchain-openai
|
||||||
|
|
||||||
|
missing = [
|
||||||
|
name
|
||||||
|
for name, value in {
|
||||||
|
"api_key": cfg.api_key,
|
||||||
|
"azure_endpoint": cfg.azure_endpoint,
|
||||||
|
"azure_deployment": cfg.azure_deployment,
|
||||||
|
"api_version": cfg.api_version,
|
||||||
|
}.items()
|
||||||
|
if not value
|
||||||
|
]
|
||||||
|
if missing:
|
||||||
|
raise ValueError(f"Missing Azure settings: {', '.join(missing)}")
|
||||||
|
|
||||||
|
return AzureChatOpenAI(
|
||||||
|
api_key=cfg.api_key,
|
||||||
|
azure_endpoint=cfg.azure_endpoint,
|
||||||
|
azure_deployment=cfg.azure_deployment,
|
||||||
|
api_version=cfg.api_version,
|
||||||
|
temperature=cfg.temperature,
|
||||||
|
)
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise ValueError(f"Unsupported provider: {cfg.provider}")
|
||||||
|
|
||||||
|
|
||||||
|
def build_embeddings(cfg: EmbeddingsConfig):
|
||||||
|
match cfg.provider:
|
||||||
|
case Provider.OLLAMA:
|
||||||
|
return OllamaEmbeddings(
|
||||||
|
model=cfg.model,
|
||||||
|
base_url=cfg.ollama_base_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.OPENAI:
|
||||||
|
from langchain_openai import OpenAIEmbeddings # pip install langchain-openai
|
||||||
|
|
||||||
|
if not cfg.api_key:
|
||||||
|
raise ValueError("Missing api_key for OpenAI embeddings provider.")
|
||||||
|
return OpenAIEmbeddings(
|
||||||
|
model=cfg.model,
|
||||||
|
api_key=cfg.api_key,
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.AZURE_OPENAI:
|
||||||
|
from langchain_openai import AzureOpenAIEmbeddings # pip install langchain-openai
|
||||||
|
|
||||||
|
missing = [
|
||||||
|
name
|
||||||
|
for name, value in {
|
||||||
|
"api_key": cfg.api_key,
|
||||||
|
"azure_endpoint": cfg.azure_endpoint,
|
||||||
|
"azure_deployment": cfg.azure_deployment,
|
||||||
|
"api_version": cfg.api_version,
|
||||||
|
}.items()
|
||||||
|
if not value
|
||||||
|
]
|
||||||
|
if missing:
|
||||||
|
raise ValueError(f"Missing Azure settings: {', '.join(missing)}")
|
||||||
|
|
||||||
|
return AzureOpenAIEmbeddings(
|
||||||
|
api_key=cfg.api_key,
|
||||||
|
azure_endpoint=cfg.azure_endpoint,
|
||||||
|
azure_deployment=cfg.azure_deployment,
|
||||||
|
api_version=cfg.api_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise ValueError(f"Unsupported embeddings provider: {cfg.provider}")
|
||||||
|
|
@ -0,0 +1,179 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from enum import StrEnum
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- Providers ----------
|
||||||
|
class Provider(StrEnum):
|
||||||
|
OLLAMA = "ollama"
|
||||||
|
OPENAI = "openai"
|
||||||
|
ANTHROPIC = "anthropic"
|
||||||
|
AWS_BEDROCK = "aws_bedrock"
|
||||||
|
HUGGINGFACE = "huggingface"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- Provider-specific configs ----------
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class OllamaCfg:
|
||||||
|
base_url: Optional[str] = None
|
||||||
|
validate_model_on_init: bool = True
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class OpenAICfg:
|
||||||
|
api_key: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class AnthropicCfg:
|
||||||
|
api_key: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class BedrockCfg:
|
||||||
|
# depende de cómo autentiques: env vars, perfil AWS, role, etc.
|
||||||
|
region_name: Optional[str] = None
|
||||||
|
# model_kwargs típicos: temperature, max_tokens, etc. (según wrapper)
|
||||||
|
# lo dejamos mínimo para no acoplar
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class HuggingFaceCfg:
|
||||||
|
# puede ser token HF o endpoint, según uses Inference API o local
|
||||||
|
api_key: Optional[str] = None
|
||||||
|
endpoint_url: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- Base configs ----------
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ChatModelConfig:
|
||||||
|
provider: Provider
|
||||||
|
model: str
|
||||||
|
temperature: float = 0.0
|
||||||
|
|
||||||
|
# EXACTAMENTE una de estas debería venir informada según provider:
|
||||||
|
ollama: Optional[OllamaCfg] = None
|
||||||
|
openai: Optional[OpenAICfg] = None
|
||||||
|
anthropic: Optional[AnthropicCfg] = None
|
||||||
|
bedrock: Optional[BedrockCfg] = None
|
||||||
|
huggingface: Optional[HuggingFaceCfg] = None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class EmbeddingsConfig:
|
||||||
|
provider: Provider
|
||||||
|
model: str
|
||||||
|
|
||||||
|
ollama: Optional[OllamaCfg] = None
|
||||||
|
openai: Optional[OpenAICfg] = None
|
||||||
|
bedrock: Optional[BedrockCfg] = None
|
||||||
|
huggingface: Optional[HuggingFaceCfg] = None
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- Helpers ----------
|
||||||
|
def _require(value, msg: str):
|
||||||
|
if value is None:
|
||||||
|
raise ValueError(msg)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def _require_cfg(cfg_obj, msg: str):
|
||||||
|
if cfg_obj is None:
|
||||||
|
raise ValueError(msg)
|
||||||
|
return cfg_obj
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- Builders ----------
|
||||||
|
def build_chat_model(cfg: ChatModelConfig):
|
||||||
|
match cfg.provider:
|
||||||
|
case Provider.OLLAMA:
|
||||||
|
from langchain_ollama import ChatOllama
|
||||||
|
|
||||||
|
ocfg = cfg.ollama or OllamaCfg()
|
||||||
|
return ChatOllama(
|
||||||
|
model=cfg.model,
|
||||||
|
temperature=cfg.temperature,
|
||||||
|
validate_model_on_init=ocfg.validate_model_on_init,
|
||||||
|
base_url=ocfg.base_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.OPENAI:
|
||||||
|
from langchain_openai import ChatOpenAI # pip install langchain-openai
|
||||||
|
|
||||||
|
ocfg = _require_cfg(cfg.openai, "Missing cfg.openai for OpenAI provider.")
|
||||||
|
return ChatOpenAI(
|
||||||
|
model=cfg.model,
|
||||||
|
temperature=cfg.temperature,
|
||||||
|
api_key=ocfg.api_key,
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.ANTHROPIC:
|
||||||
|
from langchain_anthropic import ChatAnthropic # pip install langchain-anthropic
|
||||||
|
|
||||||
|
acfg = _require_cfg(cfg.anthropic, "Missing cfg.anthropic for Anthropic provider.")
|
||||||
|
return ChatAnthropic(
|
||||||
|
model=cfg.model,
|
||||||
|
temperature=cfg.temperature,
|
||||||
|
api_key=acfg.api_key,
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.AWS_BEDROCK:
|
||||||
|
# wrapper típico: langchain-aws (según versión) o langchain-community en algunos setups
|
||||||
|
# aquí lo dejo como ejemplo con guardrail claro
|
||||||
|
try:
|
||||||
|
from langchain_aws import ChatBedrock # pip install langchain-aws
|
||||||
|
except Exception as e:
|
||||||
|
raise ImportError(
|
||||||
|
"To use AWS Bedrock, install `langchain-aws` and configure AWS credentials."
|
||||||
|
) from e
|
||||||
|
|
||||||
|
bcfg = cfg.bedrock or BedrockCfg()
|
||||||
|
# OJO: ChatBedrock suele usar model_id en vez de model, depende del wrapper/versión.
|
||||||
|
return ChatBedrock(
|
||||||
|
model_id=cfg.model,
|
||||||
|
region_name=bcfg.region_name,
|
||||||
|
model_kwargs={"temperature": cfg.temperature},
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.HUGGINGFACE:
|
||||||
|
# depende MUCHO: endpoint, local pipeline, inference API...
|
||||||
|
raise NotImplementedError(
|
||||||
|
"HUGGINGFACE provider not implemented here (depends on whether you use Inference API, TGI, or local pipeline)."
|
||||||
|
)
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise ValueError(f"Unsupported provider: {cfg.provider}")
|
||||||
|
|
||||||
|
|
||||||
|
def build_embeddings(cfg: EmbeddingsConfig):
|
||||||
|
match cfg.provider:
|
||||||
|
case Provider.OLLAMA:
|
||||||
|
from langchain_ollama import OllamaEmbeddings
|
||||||
|
|
||||||
|
ocfg = cfg.ollama or OllamaCfg()
|
||||||
|
return OllamaEmbeddings(
|
||||||
|
model=cfg.model,
|
||||||
|
base_url=ocfg.base_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.OPENAI:
|
||||||
|
from langchain_openai import OpenAIEmbeddings # pip install langchain-openai
|
||||||
|
|
||||||
|
ocfg = _require_cfg(cfg.openai, "Missing cfg.openai for OpenAI embeddings provider.")
|
||||||
|
return OpenAIEmbeddings(
|
||||||
|
model=cfg.model,
|
||||||
|
api_key=ocfg.api_key,
|
||||||
|
)
|
||||||
|
|
||||||
|
case Provider.AWS_BEDROCK:
|
||||||
|
# Igual: depende del wrapper
|
||||||
|
raise NotImplementedError("Bedrock embeddings: añade el wrapper que uses y mapea aquí.")
|
||||||
|
|
||||||
|
case Provider.HUGGINGFACE:
|
||||||
|
raise NotImplementedError("HuggingFace embeddings: depende del wrapper (endpoint/local).")
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise ValueError(f"Unsupported embeddings provider: {cfg.provider}")
|
||||||
Loading…
Reference in New Issue