2024-02-21 01:21:19 +00:00
package config
2023-07-14 23:19:43 +00:00
import (
2024-01-05 17:04:46 +00:00
"errors"
2023-07-14 23:19:43 +00:00
"fmt"
2024-01-05 17:04:46 +00:00
"io/fs"
2023-07-14 23:19:43 +00:00
"os"
2024-01-05 17:04:46 +00:00
"path/filepath"
"strings"
"sync"
2023-07-14 23:19:43 +00:00
2024-01-05 22:16:33 +00:00
"github.com/go-skynet/LocalAI/pkg/downloader"
2023-12-18 17:58:44 +00:00
"github.com/go-skynet/LocalAI/pkg/utils"
2024-01-05 17:04:46 +00:00
"github.com/rs/zerolog/log"
2023-07-14 23:19:43 +00:00
"gopkg.in/yaml.v3"
)
type Config struct {
PredictionOptions ` yaml:"parameters" `
2023-08-09 06:38:51 +00:00
Name string ` yaml:"name" `
F16 bool ` yaml:"f16" `
Threads int ` yaml:"threads" `
Debug bool ` yaml:"debug" `
Roles map [ string ] string ` yaml:"roles" `
Embeddings bool ` yaml:"embeddings" `
Backend string ` yaml:"backend" `
TemplateConfig TemplateConfig ` yaml:"template" `
PromptStrings , InputStrings [ ] string ` yaml:"-" `
InputToken [ ] [ ] int ` yaml:"-" `
functionCallString , functionCallNameString string ` yaml:"-" `
2023-07-14 23:19:43 +00:00
FunctionsConfig Functions ` yaml:"function" `
2023-07-22 15:31:39 +00:00
2023-08-19 14:15:22 +00:00
FeatureFlag FeatureFlag ` yaml:"feature_flags" ` // Feature Flag registry. We move fast, and features may break on a per model/backend basis. Registry for (usually temporary) flags that indicate aborting something early.
2023-08-09 06:38:51 +00:00
// LLM configs (GPT4ALL, Llama.cpp, ...)
LLMConfig ` yaml:",inline" `
// AutoGPTQ specifics
AutoGPTQ AutoGPTQ ` yaml:"autogptq" `
2023-08-02 22:51:08 +00:00
2023-08-09 06:38:51 +00:00
// Diffusers
Diffusers Diffusers ` yaml:"diffusers" `
2023-12-13 18:20:22 +00:00
Step int ` yaml:"step" `
2023-08-15 23:11:32 +00:00
// GRPC Options
GRPC GRPC ` yaml:"grpc" `
2023-09-04 17:25:23 +00:00
// Vall-e-x
VallE VallE ` yaml:"vall-e" `
2023-12-08 14:45:04 +00:00
// CUDA
// Explicitly enable CUDA or not (some backends might need it)
CUDA bool ` yaml:"cuda" `
2024-01-01 13:39:13 +00:00
DownloadFiles [ ] File ` yaml:"download_files" `
2024-01-07 23:37:02 +00:00
Description string ` yaml:"description" `
Usage string ` yaml:"usage" `
2024-01-01 13:39:13 +00:00
}
type File struct {
Filename string ` yaml:"filename" json:"filename" `
SHA256 string ` yaml:"sha256" json:"sha256" `
URI string ` yaml:"uri" json:"uri" `
2023-09-04 17:25:23 +00:00
}
type VallE struct {
AudioPath string ` yaml:"audio_path" `
2023-08-15 23:11:32 +00:00
}
2023-08-19 14:15:22 +00:00
type FeatureFlag map [ string ] * bool
func ( ff FeatureFlag ) Enabled ( s string ) bool {
v , exist := ff [ s ]
return exist && v != nil && * v
}
2023-08-15 23:11:32 +00:00
type GRPC struct {
Attempts int ` yaml:"attempts" `
AttemptsSleepTime int ` yaml:"attempts_sleep_time" `
2023-08-09 06:38:51 +00:00
}
type Diffusers struct {
2023-12-15 23:06:20 +00:00
CUDA bool ` yaml:"cuda" `
2023-08-15 23:11:42 +00:00
PipelineType string ` yaml:"pipeline_type" `
SchedulerType string ` yaml:"scheduler_type" `
EnableParameters string ` yaml:"enable_parameters" ` // A list of comma separated parameters to specify
CFGScale float32 ` yaml:"cfg_scale" ` // Classifier-Free Guidance Scale
2023-08-17 21:38:59 +00:00
IMG2IMG bool ` yaml:"img2img" ` // Image to Image Diffuser
ClipSkip int ` yaml:"clip_skip" ` // Skip every N frames
ClipModel string ` yaml:"clip_model" ` // Clip model to use
ClipSubFolder string ` yaml:"clip_subfolder" ` // Subfolder to use for clip model
2023-12-13 18:20:22 +00:00
ControlNet string ` yaml:"control_net" `
2023-08-09 06:38:51 +00:00
}
type LLMConfig struct {
SystemPrompt string ` yaml:"system_prompt" `
TensorSplit string ` yaml:"tensor_split" `
MainGPU string ` yaml:"main_gpu" `
RMSNormEps float32 ` yaml:"rms_norm_eps" `
NGQA int32 ` yaml:"ngqa" `
PromptCachePath string ` yaml:"prompt_cache_path" `
PromptCacheAll bool ` yaml:"prompt_cache_all" `
PromptCacheRO bool ` yaml:"prompt_cache_ro" `
MirostatETA float64 ` yaml:"mirostat_eta" `
MirostatTAU float64 ` yaml:"mirostat_tau" `
Mirostat int ` yaml:"mirostat" `
NGPULayers int ` yaml:"gpu_layers" `
MMap bool ` yaml:"mmap" `
MMlock bool ` yaml:"mmlock" `
LowVRAM bool ` yaml:"low_vram" `
Grammar string ` yaml:"grammar" `
StopWords [ ] string ` yaml:"stopwords" `
Cutstrings [ ] string ` yaml:"cutstrings" `
TrimSpace [ ] string ` yaml:"trimspace" `
2024-01-01 13:39:42 +00:00
TrimSuffix [ ] string ` yaml:"trimsuffix" `
ContextSize int ` yaml:"context_size" `
NUMA bool ` yaml:"numa" `
LoraAdapter string ` yaml:"lora_adapter" `
LoraBase string ` yaml:"lora_base" `
LoraScale float32 ` yaml:"lora_scale" `
NoMulMatQ bool ` yaml:"no_mulmatq" `
DraftModel string ` yaml:"draft_model" `
NDraft int32 ` yaml:"n_draft" `
Quantization string ` yaml:"quantization" `
MMProj string ` yaml:"mmproj" `
2023-11-11 17:40:48 +00:00
2024-01-25 23:13:21 +00:00
RopeScaling string ` yaml:"rope_scaling" `
ModelType string ` yaml:"type" `
2023-11-11 17:40:48 +00:00
YarnExtFactor float32 ` yaml:"yarn_ext_factor" `
YarnAttnFactor float32 ` yaml:"yarn_attn_factor" `
YarnBetaFast float32 ` yaml:"yarn_beta_fast" `
YarnBetaSlow float32 ` yaml:"yarn_beta_slow" `
2023-08-09 06:38:51 +00:00
}
2023-08-07 20:39:10 +00:00
2023-08-09 06:38:51 +00:00
type AutoGPTQ struct {
2023-08-07 23:10:05 +00:00
ModelBaseName string ` yaml:"model_base_name" `
Device string ` yaml:"device" `
Triton bool ` yaml:"triton" `
UseFastTokenizer bool ` yaml:"use_fast_tokenizer" `
2023-07-14 23:19:43 +00:00
}
type Functions struct {
DisableNoAction bool ` yaml:"disable_no_action" `
NoActionFunctionName string ` yaml:"no_action_function_name" `
NoActionDescriptionName string ` yaml:"no_action_description_name" `
2024-02-20 20:58:45 +00:00
ParallelCalls bool ` yaml:"parallel_calls" `
2023-07-14 23:19:43 +00:00
}
type TemplateConfig struct {
2023-07-22 15:31:39 +00:00
Chat string ` yaml:"chat" `
ChatMessage string ` yaml:"chat_message" `
Completion string ` yaml:"completion" `
Edit string ` yaml:"edit" `
Functions string ` yaml:"function" `
2023-07-14 23:19:43 +00:00
}
2024-01-05 17:04:46 +00:00
type ConfigLoader struct {
configs map [ string ] Config
sync . Mutex
}
2023-07-14 23:19:43 +00:00
func ( c * Config ) SetFunctionCallString ( s string ) {
c . functionCallString = s
}
func ( c * Config ) SetFunctionCallNameString ( s string ) {
c . functionCallNameString = s
}
func ( c * Config ) ShouldUseFunctions ( ) bool {
return ( ( c . functionCallString != "none" || c . functionCallString == "" ) || c . ShouldCallSpecificFunction ( ) )
}
func ( c * Config ) ShouldCallSpecificFunction ( ) bool {
return len ( c . functionCallNameString ) > 0
}
func ( c * Config ) FunctionToCall ( ) string {
return c . functionCallNameString
}
2024-02-10 20:37:03 +00:00
// Load a config file for a model
func Load ( modelName , modelPath string , cm * ConfigLoader , debug bool , threads , ctx int , f16 bool ) ( * Config , error ) {
// Load a config file if present after the model name
modelConfig := filepath . Join ( modelPath , modelName + ".yaml" )
var cfg * Config
defaults := func ( ) {
cfg = DefaultConfig ( modelName )
cfg . ContextSize = ctx
cfg . Threads = threads
cfg . F16 = f16
cfg . Debug = debug
}
cfgExisting , exists := cm . GetConfig ( modelName )
if ! exists {
if _ , err := os . Stat ( modelConfig ) ; err == nil {
if err := cm . LoadConfig ( modelConfig ) ; err != nil {
return nil , fmt . Errorf ( "failed loading model config (%s) %s" , modelConfig , err . Error ( ) )
}
cfgExisting , exists = cm . GetConfig ( modelName )
if exists {
cfg = & cfgExisting
} else {
defaults ( )
}
} else {
defaults ( )
}
} else {
cfg = & cfgExisting
}
// Set the parameters for the language model prediction
//updateConfig(cfg, input)
// Don't allow 0 as setting
if cfg . Threads == 0 {
if threads != 0 {
cfg . Threads = threads
} else {
cfg . Threads = 4
}
}
// Enforce debug flag if passed from CLI
if debug {
cfg . Debug = true
}
return cfg , nil
}
2023-07-14 23:19:43 +00:00
func defaultPredictOptions ( modelFile string ) PredictionOptions {
return PredictionOptions {
TopP : 0.7 ,
TopK : 80 ,
Maxtokens : 512 ,
Temperature : 0.9 ,
Model : modelFile ,
}
}
func DefaultConfig ( modelFile string ) * Config {
return & Config {
PredictionOptions : defaultPredictOptions ( modelFile ) ,
}
}
2024-01-05 17:04:46 +00:00
func NewConfigLoader ( ) * ConfigLoader {
return & ConfigLoader {
configs : make ( map [ string ] Config ) ,
}
}
2023-07-14 23:19:43 +00:00
func ReadConfigFile ( file string ) ( [ ] * Config , error ) {
c := & [ ] * Config { }
f , err := os . ReadFile ( file )
if err != nil {
return nil , fmt . Errorf ( "cannot read config file: %w" , err )
}
if err := yaml . Unmarshal ( f , c ) ; err != nil {
return nil , fmt . Errorf ( "cannot unmarshal config file: %w" , err )
}
return * c , nil
}
2024-01-05 17:04:46 +00:00
func ReadConfig ( file string ) ( * Config , error ) {
2023-07-14 23:19:43 +00:00
c := & Config { }
f , err := os . ReadFile ( file )
if err != nil {
return nil , fmt . Errorf ( "cannot read config file: %w" , err )
}
if err := yaml . Unmarshal ( f , c ) ; err != nil {
return nil , fmt . Errorf ( "cannot unmarshal config file: %w" , err )
}
return c , nil
}
2024-01-05 17:04:46 +00:00
func ( cm * ConfigLoader ) LoadConfigFile ( file string ) error {
cm . Lock ( )
defer cm . Unlock ( )
c , err := ReadConfigFile ( file )
if err != nil {
return fmt . Errorf ( "cannot load config file: %w" , err )
2024-01-05 14:34:56 +00:00
}
2023-12-30 14:36:46 +00:00
2024-01-05 17:04:46 +00:00
for _ , cc := range c {
cm . configs [ cc . Name ] = * cc
2024-01-05 14:34:56 +00:00
}
2024-01-05 17:04:46 +00:00
return nil
}
2023-12-30 14:36:46 +00:00
2024-01-05 17:04:46 +00:00
func ( cm * ConfigLoader ) LoadConfig ( file string ) error {
cm . Lock ( )
defer cm . Unlock ( )
c , err := ReadConfig ( file )
if err != nil {
return fmt . Errorf ( "cannot read config file: %w" , err )
2024-01-05 14:34:56 +00:00
}
2024-01-01 13:39:13 +00:00
2024-01-05 17:04:46 +00:00
cm . configs [ c . Name ] = * c
return nil
}
2024-01-01 13:39:13 +00:00
2024-01-05 17:04:46 +00:00
func ( cm * ConfigLoader ) GetConfig ( m string ) ( Config , bool ) {
cm . Lock ( )
defer cm . Unlock ( )
v , exists := cm . configs [ m ]
return v , exists
}
2024-01-05 14:34:56 +00:00
2024-01-05 17:04:46 +00:00
func ( cm * ConfigLoader ) GetAllConfigs ( ) [ ] Config {
cm . Lock ( )
defer cm . Unlock ( )
var res [ ] Config
for _ , v := range cm . configs {
res = append ( res , v )
2024-01-05 14:34:56 +00:00
}
2024-01-05 17:04:46 +00:00
return res
}
2024-01-05 14:34:56 +00:00
2024-01-05 17:04:46 +00:00
func ( cm * ConfigLoader ) ListConfigs ( ) [ ] string {
cm . Lock ( )
defer cm . Unlock ( )
var res [ ] string
for k := range cm . configs {
res = append ( res , k )
2024-01-05 14:34:56 +00:00
}
2024-01-05 17:04:46 +00:00
return res
}
2024-01-05 14:34:56 +00:00
2024-01-05 17:04:46 +00:00
// Preload prepare models if they are not local but url or huggingface repositories
func ( cm * ConfigLoader ) Preload ( modelPath string ) error {
cm . Lock ( )
defer cm . Unlock ( )
2024-01-05 14:34:56 +00:00
2024-01-05 17:04:46 +00:00
status := func ( fileName , current , total string , percent float64 ) {
utils . DisplayDownloadFunction ( fileName , current , total , percent )
2024-01-05 14:34:56 +00:00
}
2024-01-05 17:04:46 +00:00
log . Info ( ) . Msgf ( "Preloading models from %s" , modelPath )
2024-01-05 14:34:56 +00:00
2024-01-05 17:04:46 +00:00
for i , config := range cm . configs {
2024-01-05 14:34:56 +00:00
2024-01-05 17:04:46 +00:00
// Download files and verify their SHA
for _ , file := range config . DownloadFiles {
log . Debug ( ) . Msgf ( "Checking %q exists and matches SHA" , file . Filename )
2024-01-05 14:34:56 +00:00
2024-01-05 17:04:46 +00:00
if err := utils . VerifyPath ( file . Filename , modelPath ) ; err != nil {
return err
}
// Create file path
filePath := filepath . Join ( modelPath , file . Filename )
2024-01-05 14:34:56 +00:00
2024-01-05 22:16:33 +00:00
if err := downloader . DownloadFile ( file . URI , filePath , file . SHA256 , status ) ; err != nil {
2024-01-05 17:04:46 +00:00
return err
2024-01-01 13:39:13 +00:00
}
}
2024-01-05 17:04:46 +00:00
modelURL := config . PredictionOptions . Model
2024-01-05 22:16:33 +00:00
modelURL = downloader . ConvertURL ( modelURL )
2023-12-18 17:58:44 +00:00
2024-01-05 22:16:33 +00:00
if downloader . LooksLikeURL ( modelURL ) {
2024-01-05 17:04:46 +00:00
// md5 of model name
md5Name := utils . MD5 ( modelURL )
2023-12-18 17:58:44 +00:00
2024-01-05 17:04:46 +00:00
// check if file exists
if _ , err := os . Stat ( filepath . Join ( modelPath , md5Name ) ) ; errors . Is ( err , os . ErrNotExist ) {
2024-01-05 22:16:33 +00:00
err := downloader . DownloadFile ( modelURL , filepath . Join ( modelPath , md5Name ) , "" , status )
2024-01-05 17:04:46 +00:00
if err != nil {
return err
2024-01-05 14:34:56 +00:00
}
}
2024-01-05 17:04:46 +00:00
cc := cm . configs [ i ]
c := & cc
c . PredictionOptions . Model = md5Name
cm . configs [ i ] = * c
2023-07-14 23:19:43 +00:00
}
2024-01-07 23:37:02 +00:00
if cm . configs [ i ] . Name != "" {
log . Info ( ) . Msgf ( "Model name: %s" , cm . configs [ i ] . Name )
}
if cm . configs [ i ] . Description != "" {
log . Info ( ) . Msgf ( "Model description: %s" , cm . configs [ i ] . Description )
}
if cm . configs [ i ] . Usage != "" {
log . Info ( ) . Msgf ( "Model usage: \n%s" , cm . configs [ i ] . Usage )
}
2023-07-14 23:19:43 +00:00
}
2024-01-05 17:04:46 +00:00
return nil
}
2024-01-05 14:34:56 +00:00
2024-01-05 17:04:46 +00:00
func ( cm * ConfigLoader ) LoadConfigs ( path string ) error {
cm . Lock ( )
defer cm . Unlock ( )
entries , err := os . ReadDir ( path )
if err != nil {
return err
}
files := make ( [ ] fs . FileInfo , 0 , len ( entries ) )
for _ , entry := range entries {
info , err := entry . Info ( )
if err != nil {
return err
2023-07-14 23:19:43 +00:00
}
2024-01-05 17:04:46 +00:00
files = append ( files , info )
2024-01-05 14:34:56 +00:00
}
2024-01-05 17:04:46 +00:00
for _ , file := range files {
// Skip templates, YAML and .keep files
if ! strings . Contains ( file . Name ( ) , ".yaml" ) && ! strings . Contains ( file . Name ( ) , ".yml" ) {
continue
}
c , err := ReadConfig ( filepath . Join ( path , file . Name ( ) ) )
if err == nil {
cm . configs [ c . Name ] = * c
2023-07-14 23:19:43 +00:00
}
}
2024-01-05 17:04:46 +00:00
return nil
2023-07-14 23:19:43 +00:00
}