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