from __future__ import annotations
"""
    #################################################################################################################################################################################################
    # This code library is an adaptation of the original Transformers and was designed, developed and programmed by Sapiens Technology®.                                                            #
    # Any alteration and/or disclosure of this code without prior authorization is strictly prohibited and is subject to legal action that will be forwarded by the Sapiens Technology® legal team. #
    # This set of algorithms aims to download, train, fine-tune and/or infer large language models from various sources and slopes.                                                                 #
    #################################################################################################################################################################################################
"""
import multiprocessing
from typing import Optional, List, Literal, Union, Dict, cast
from typing_extensions import Self
from pydantic import Field, model_validator
from pydantic_settings import BaseSettings
import sapiens_transformers.sapiens_optimizer as sapiens_optimizer
BaseSettings.model_config["protected_namespaces"] = ()
class ModelSettings(BaseSettings):
    model: str = Field(description="The path to the model to use for generating completions.")
    model_alias: Optional[str] = Field(default=None, description="The alias of the model to use for generating completions.")
    n_gpu_layers: int = Field(default=0, ge=-1, description="The number of layers to put on the GPU. The rest will be on the CPU. Set -1 to move all to GPU.")
    split_mode: int = Field(default=sapiens_optimizer.SAPIENS_SPLIT_MODE_LAYER, description="The split mode to use.")
    main_gpu: int = Field(default=0, ge=0, description="Main GPU to use.")
    tensor_split: Optional[List[float]] = Field(default=None, description="Split layers across multiple GPUs in proportion.")
    vocab_only: bool = Field(default=False, description="Whether to only return the vocabulary.")
    use_mmap: bool = Field(default=sapiens_optimizer.llama_supports_mmap(), description="Use mmap.")
    use_mlock: bool = Field(default=sapiens_optimizer.llama_supports_mlock(), description="Use mlock.")
    kv_overrides: Optional[List[str]] = Field(default=None, description="List of model kv overrides in the format key=type:value where type is one of (bool, int, float). Valid true values are (true, TRUE, 1), otherwise false.")
    rpc_servers: Optional[str] = Field(default=None, description="comma seperated list of rpc servers for offloading")
    seed: int = Field(default=sapiens_optimizer.SAPIENS_DEFAULT_SEED, description="Random seed. -1 for random.")
    n_ctx: int = Field(default=2048, ge=0, description="The context size.")
    n_batch: int = Field(default=512, ge=1, description="The batch size to use per eval.")
    n_ubatch: int = Field(default=512, ge=1, description="The physical batch size used by llama.cpp")
    n_threads: int = Field(default=max(multiprocessing.cpu_count() // 2, 1), ge=1, description="The number of threads to use. Use -1 for max cpu threads")
    n_threads_batch: int = Field(default=max(multiprocessing.cpu_count(), 1), ge=0, description="The number of threads to use when batch processing. Use -1 for max cpu threads")
    rope_scaling_type: int = Field(default=sapiens_optimizer.SAPIENS_ROPE_SCALING_TYPE_UNSPECIFIED)
    rope_freq_base: float = Field(default=0.0, description="RoPE base frequency")
    rope_freq_scale: float = Field(default=0.0, description="RoPE frequency scaling factor")
    yarn_ext_factor: float = Field(default=-1.0)
    yarn_attn_factor: float = Field(default=1.0)
    yarn_beta_fast: float = Field(default=32.0)
    yarn_beta_slow: float = Field(default=1.0)
    yarn_orig_ctx: int = Field(default=0)
    mul_mat_q: bool = Field(default=True, description="if true, use experimental mul_mat_q kernels")
    logits_all: bool = Field(default=True, description="Whether to return logits.")
    embedding: bool = Field(default=False, description="Whether to use embeddings.")
    offload_kqv: bool = Field(default=True, description="Whether to offload kqv to the GPU.")
    flash_attn: bool = Field(default=False, description="Whether to use flash attention.")
    last_n_tokens_size: int = Field(default=64, ge=0, description="Last n tokens to keep for repeat penalty calculation.")
    lora_base: Optional[str] = Field(default=None, description="Optional path to base model, useful if using a quantized base model and you want to apply LoRA to an f16 model.")
    lora_path: Optional[str] = Field(default=None, description="Path to a LoRA file to apply to the model.")
    numa: Union[bool, int] = Field(default=False, description="Enable NUMA support.")
    chat_format: Optional[str] = Field(default=None, description="Chat format to use.")
    clip_model_path: Optional[str] = Field(default=None, description="Path to a CLIP model to use for multi-modal chat completion.")
    cache: bool = Field(default=False, description="Use a cache to reduce processing times for evaluated prompts.")
    cache_type: Literal["ram", "disk"] = Field(default="ram", description="The type of cache to use. Only used if cache is True.")
    cache_size: int = Field(default=2 << 30, description="The size of the cache in bytes. Only used if cache is True.")
    hf_tokenizer_config_path: Optional[str] = Field(default=None, description="The path to a Sapiens tokenizer_config.json file.")
    hf_pretrained_model_name_or_path: Optional[str] = Field(default=None, description="The model name or path to a pretrained Sapiens tokenizer model. Same as you would pass to AutoTokenizer.from_pretrained().")
    hf_model_repo_id: Optional[str] = Field(default=None, description="The model repo id to use for the Sapiens tokenizer model.")
    draft_model: Optional[str] = Field(default=None, description="Method to use for speculative decoding. One of (prompt-lookup-decoding).")
    draft_model_num_pred_tokens: int = Field(default=10, description="Number of tokens to predict using the draft model.")
    type_k: Optional[int] = Field(default=None, description="Type of the key cache quantization.")
    type_v: Optional[int] = Field(default=None, description="Type of the value cache quantization.")
    verbose: bool = Field(default=True, description="Whether to print debug information.")
    @model_validator(mode="before")
    def set_dynamic_defaults(self) -> Self:
        cpu_count = multiprocessing.cpu_count()
        values = cast(Dict[str, int], self)
        if values.get("n_threads", 0) == -1: values["n_threads"] = cpu_count
        if values.get("n_threads_batch", 0) == -1: values["n_threads_batch"] = cpu_count
        return self
class ServerSettings(BaseSettings):
    host: str = Field(default="localhost", description="Listen address")
    port: int = Field(default=8000, description="Listen port")
    ssl_keyfile: Optional[str] = Field(default=None, description="SSL key file for HTTPS")
    ssl_certfile: Optional[str] = Field(default=None, description="SSL certificate file for HTTPS")
    api_key: Optional[str] = Field(default=None, description="API key for authentication. If set all requests need to be authenticated.")
    interrupt_requests: bool = Field(default=True, description="Whether to interrupt requests when a new request is received.")
    disable_ping_events: bool = Field(default=False, description="Disable EventSource pings (may be needed for some clients).")
    root_path: str = Field(default="", description="The root path for the server. Useful when running behind a reverse proxy.")
class Settings(ServerSettings, ModelSettings): pass
class ConfigFileSettings(ServerSettings):
    models: List[ModelSettings] = Field(default=[], description="Model configs")
"""
    #################################################################################################################################################################################################
    # This code library is an adaptation of the original Transformers and was designed, developed and programmed by Sapiens Technology®.                                                            #
    # Any alteration and/or disclosure of this code without prior authorization is strictly prohibited and is subject to legal action that will be forwarded by the Sapiens Technology® legal team. #
    # This set of algorithms aims to download, train, fine-tune and/or infer large language models from various sources and slopes.                                                                 #
    #################################################################################################################################################################################################
"""
