localmodel

package
v1.4.4-alpha1202-diff-... Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 2, 2025 License: AGPL-3.0 Imports: 25 Imported by: 0

README

Local Model Manager

本地模型管理器用于管理和控制本地AI模型服务,特别是基于 llama-server 的嵌入服务。

功能特性

  • 服务生命周期管理: 启动、停止、状态监控
  • 配置灵活: 支持选项模式配置服务参数
  • 并发安全: 使用读写锁确保并发操作安全
  • 错误处理: 完善的错误处理和状态跟踪
  • 模型支持: 内置支持多种模型配置

快速开始

获取管理器

本模块使用单例模式,通过 GetManager() 获取管理器实例:

import "github.com/yaklang/yaklang/common/ai/localmodel"

// 获取管理器单例实例
manager := localmodel.GetManager()
启动嵌入服务
err := manager.StartEmbeddingService(
    "127.0.0.1:11434",
    localmodel.WithEmbeddingModel("Qwen3-Embedding-0.6B-Q4_K_M"),
    localmodel.WithDetached(true),
    localmodel.WithDebug(true),
    localmodel.WithModelPath("/path/to/model.gguf"),
    localmodel.WithContextSize(4096),
    localmodel.WithContBatching(true),
    localmodel.WithBatchSize(1024),
    localmodel.WithThreads(8),
)
if err != nil {
    log.Fatal(err)
}

本地模型管理

检查本地模型
// 检查默认模型是否可用
if manager.IsDefaultModelAvailable() {
    fmt.Println("默认模型可用")
    fmt.Printf("路径: %s\n", manager.GetDefaultEmbeddingModelPath())
}

// 检查特定模型是否存在
if manager.IsLocalModelExists("Qwen3-Embedding-0.6B-Q4_K_M") {
    fmt.Println("Qwen3 模型可用")
}

// 列出所有本地可用的模型
localModels := manager.ListLocalModels()
fmt.Printf("本地可用模型: %v\n", localModels)
获取模型路径
// 获取默认嵌入模型路径
defaultPath := manager.GetDefaultEmbeddingModelPath()
fmt.Printf("默认模型路径: %s\n", defaultPath)

// 获取特定模型的本地路径
modelPath, err := manager.GetLocalModelPath("Qwen3-Embedding-0.6B-Q4_K_M")
if err != nil {
    log.Printf("获取模型路径失败: %v", err)
} else {
    fmt.Printf("模型路径: %s\n", modelPath)
}
自动模型路径检测

如果不指定模型路径,管理器会自动使用默认路径:

// 不指定模型路径,将自动使用默认的 Qwen3 模型路径
err := manager.StartEmbeddingService("127.0.0.1:8080")
if err != nil {
    log.Fatal(err)
}

配置选项

可用选项
  • WithHost(host string): 设置服务主机地址
  • WithPort(port int32): 设置服务端口
  • WithEmbeddingModel(model string): 设置嵌入模型名称
  • WithModelPath(path string): 设置模型文件路径
  • WithContextSize(size int): 设置上下文大小
  • WithContBatching(enabled bool): 设置是否启用连续批处理
  • WithBatchSize(size int): 设置批处理大小
  • WithThreads(threads int): 设置线程数
  • WithDetached(detached bool): 设置是否分离模式
  • WithDebug(debug bool): 设置调试模式
  • WithStartupTimeout(timeout time.Duration): 设置启动超时时间
  • WithArgs(args ...string): 设置额外的命令行参数
默认配置
config := localmodel.DefaultServiceConfig()
// Host: "127.0.0.1"
// Port: 8080
// ContextSize: 4096
// ContBatching: true
// BatchSize: 1024
// Threads: 8
// Detached: false
// Debug: false
// StartupTimeout: 30 * time.Second

服务管理

查看服务状态
// 获取特定服务状态
status, err := manager.GetServiceStatus("service-name")
if err != nil {
    log.Printf("Service not found: %v", err)
} else {
    fmt.Printf("Service: %s, Status: %s\n", status.Name, status.Status)
}

// 列出所有服务
services := manager.ListServices()
for _, service := range services {
    fmt.Printf("Service: %s, Status: %s, Started: %v\n", 
        service.Name, service.Status, service.StartTime)
}
停止服务
// 停止特定服务
err := manager.StopService("service-name")
if err != nil {
    log.Printf("Failed to stop service: %v", err)
}

// 停止所有服务
err := manager.StopAllServices()
if err != nil {
    log.Printf("Failed to stop all services: %v", err)
}

服务状态

服务具有以下状态:

  • StatusStopped: 已停止
  • StatusStarting: 启动中
  • StatusRunning: 运行中
  • StatusStopping: 停止中
  • StatusError: 错误状态

支持的模型

获取支持的模型列表
models := localmodel.GetSupportedModels()
for _, model := range models {
    fmt.Printf("Model: %s (%s)\n", model.Name, model.Type)
    fmt.Printf("Description: %s\n", model.Description)
    fmt.Printf("Default Port: %d\n", model.DefaultPort)
}
查找特定模型
model, err := localmodel.FindModelConfig("Qwen3-Embedding-0.6B-Q4_K_M")
if err != nil {
    log.Printf("Model not supported: %v", err)
} else {
    fmt.Printf("Found model: %s\n", model.Name)
}
检查模型支持
if localmodel.IsModelSupported("Qwen3-Embedding-0.6B-Q4_K_M") {
    fmt.Println("Model is supported")
} else {
    fmt.Println("Model is not supported")
}

错误处理

管理器提供详细的错误信息:

err := manager.StartEmbeddingService("invalid-address")
if err != nil {
    // 错误信息包含具体的失败原因
    log.Printf("Failed to start service: %v", err)
}

常见错误类型:

  • 地址格式错误
  • 模型文件不存在
  • llama-server 未安装
  • 端口已被占用
  • 服务已在运行

完整示例

package main

import (
    "fmt"
    "log"
    "time"
    
    "github.com/yaklang/yaklang/common/ai/localmodel"
)

func main() {
    // 获取管理器单例
    manager := localmodel.GetManager()

    // 启动嵌入服务
    err := manager.StartEmbeddingService(
        "127.0.0.1:8080",
        localmodel.WithEmbeddingModel("Qwen3-Embedding-0.6B-Q4_K_M"),
        localmodel.WithContextSize(4096),
        localmodel.WithContBatching(true),
        localmodel.WithBatchSize(1024),
        localmodel.WithThreads(8),
        localmodel.WithDebug(true),
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Service started, waiting...")
    time.Sleep(5 * time.Second)

    // 查看服务状态
    services := manager.ListServices()
    for _, service := range services {
        fmt.Printf("Service: %s, Status: %s\n", service.Name, service.Status)
    }

    // 停止服务
    err = manager.StopAllServices()
    if err != nil {
        log.Printf("Error stopping services: %v", err)
    }

    fmt.Println("All services stopped")
}

注意事项

  1. llama-server 依赖: 确保 llama-server 已正确安装并可在系统路径中找到
  2. 模型文件: 确保模型文件存在于指定路径
  3. 端口冲突: 避免多个服务使用相同端口
  4. 资源管理: 及时停止不需要的服务以释放资源
  5. 错误处理: 始终检查函数返回的错误信息

命令行工具

模块提供了一个命令行工具用于测试和管理本地模型服务:

构建和运行
# 构建命令行工具
go build -o localmodel-cli ./common/ai/localmodel/cmd

# 查看帮助
./localmodel-cli -h

# 列出支持的模型
./localmodel-cli -list-models

# 检查本地模型状态
./localmodel-cli -check-model

# 启动默认嵌入服务
./localmodel-cli

# 启动自定义配置的服务
./localmodel-cli -host 0.0.0.0 -port 9090 -debug -parallelism 4

# 使用自定义模型路径
./localmodel-cli -model-path /path/to/model.gguf -debug
命令行选项
  • -host: 服务主机地址 (默认: 127.0.0.1)
  • -port: 服务端口 (默认: 8080)
  • -model: 模型名称 (默认: Qwen3-Embedding-0.6B-Q4_K_M)
  • -model-path: 模型文件路径 (可选)
  • -context-size: 上下文大小 (默认: 4096)
  • -cont-batching: 启用连续批处理 (默认: true)
  • -batch-size: 批处理大小 (默认: 1024)
  • -threads: 线程数 (默认: 8)
  • -detached: 分离模式
  • -debug: 调试模式
  • -timeout: 启动超时时间 (默认: 30秒)
  • -list-models: 列出支持的模型
  • -check-model: 检查本地模型是否可用
示例输出
$ ./localmodel-cli -check-model
=== Yaklang Local Model Manager ===

检查本地模型:
1. 默认嵌入模型 (Qwen3-Embedding-0.6B-Q4_K_M):
   路径: /Users/user/yakit-projects/libs/models/Qwen3-Embedding-0.6B-Q4_K_M.gguf
   可用: true

2. llama-server:
   路径: /Users/user/yakit-projects/libs/llama-server
   状态: 可用

3. 所有支持的模型:
   Qwen3-Embedding-0.6B-Q4_K_M: 可用

Documentation

Overview

Example (WithOptions)

Example_withOptions 演示如何使用选项模式

config := DefaultServiceConfig()

fmt.Printf("Default config:\n")
fmt.Printf("Host: %s, Port: %d\n", config.Host, config.Port)
fmt.Printf("Context Size: %d, Cont Batching: %t\n", config.ContextSize, config.ContBatching)
fmt.Printf("Batch Size: %d, Threads: %d\n", config.BatchSize, config.Threads)

// 应用选项
options := []Option{
	WithHost("0.0.0.0"),
	WithPort(9090),
	WithContextSize(8192),
	WithContBatching(false),
	WithBatchSize(2048),
	WithThreads(16),
	WithDebug(true),
}

for _, option := range options {
	option(config)
}

fmt.Printf("\nAfter applying options:\n")
fmt.Printf("Host: %s, Port: %d\n", config.Host, config.Port)
fmt.Printf("Context Size: %d, Cont Batching: %t\n", config.ContextSize, config.ContBatching)
fmt.Printf("Batch Size: %d, Threads: %d\n", config.BatchSize, config.Threads)

Index

Examples

Constants

View Source
const (
	// 服务状态常量
	Stopped  = StatusStopped
	Starting = StatusStarting
	Running  = StatusRunning
	Stopping = StatusStopping
	Error    = StatusError
)

导出的常量

Variables

View Source
var (
	// GetManager 获取管理器单例
	GetManagerInstance = GetManager

	// NewManager 创建管理器 (已废弃)
	New = NewManager

	// 配置相关
	DefaultConfig  = DefaultServiceConfig
	GetModels      = GetSupportedModels
	FindModel      = FindModelConfig
	ValidateModel  = ValidateModelPath
	GetModel       = GetModelPath
	GetLlamaServer = GetLlamaServerPath
)

导出的函数

View Source
var ErrServiceNotFound = errors.New("service not found")

ErrServiceNotFound 服务不存在错误

Functions

func GetDefaultEmbeddingModelPath

func GetDefaultEmbeddingModelPath() string

func GetDefaultYakBinaryPath

func GetDefaultYakBinaryPath() string

GetDefaultYakBinaryPath 获取默认的 yak 二进制文件路径

func GetLlamaServerPath

func GetLlamaServerPath() (string, error)

GetLlamaServerPath 获取 llama-server 路径

func GetModelPath

func GetModelPath(modelName string) (string, error)

GetModelPath 获取模型文件路径

func GetSupportedModelNames

func GetSupportedModelNames() []string

GetSupportedModelNames 获取支持的模型名称列表

func IsDefaultModelAvailable

func IsDefaultModelAvailable() bool

func IsModelSupported

func IsModelSupported(modelName string) bool

IsModelSupported 检查模型是否被支持

func StartChat

func StartChat(address string, options ...Option) error

StartChat 启动聊天服务(便捷函数)

func StartEmbedding

func StartEmbedding(address string, options ...Option) error

StartEmbedding 启动嵌入服务(便捷函数)

func StopAllServices

func StopAllServices() error

StopAllServices 停止所有服务(便捷函数)

func StopService

func StopService(serviceName string) error

StopService 停止指定服务(便捷函数)

func ValidateModelPath

func ValidateModelPath(modelPath string) error

ValidateModelPath 验证模型路径

func WaitForEmbedding

func WaitForEmbedding(address string, timeoutSeconds float64) error

WaitForEmbedding 等待嵌入服务启动(便捷函数)

Types

type Config

type Config = ServiceConfig

ServiceConfig 服务配置

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager 本地模型管理器

func GetManager

func GetManager() *Manager

GetManager 获取管理器单例实例

func GetManagerWithDefaults

func GetManagerWithDefaults() *Manager

GetManagerWithDefaults 获取管理器单例实例

func NewManager

func NewManager() *Manager

NewManager 创建新的管理器实例 (已废弃,使用 GetManager 代替) Deprecated: Use GetManager() instead

func NewManagerWithDefaults

func NewManagerWithDefaults() *Manager

NewManagerWithDefaults 创建带默认配置的管理器 (已废弃) Deprecated: Use GetManagerWithDefaults() instead

func (*Manager) GetCurrentBinaryPathFromManager

func (m *Manager) GetCurrentBinaryPathFromManager() string

GetCurrentBinaryPathFromManager 获取当前设置的二进制文件路径

func (*Manager) GetLocalModelPath

func (m *Manager) GetLocalModelPath(modelName string) (string, error)

GetLocalModelPath 获取本地模型路径

func (*Manager) GetServiceStatus

func (m *Manager) GetServiceStatus(serviceName string) (*ServiceInfo, error)

GetServiceStatus 获取服务状态

func (*Manager) IsLocalModelExists

func (m *Manager) IsLocalModelExists(modelName string) bool

IsLocalModelExists 检查本地模型是否存在

func (*Manager) ListLocalModels

func (m *Manager) ListLocalModels() []string

ListLocalModels 列出本地可用的模型

func (*Manager) ListServices

func (m *Manager) ListServices() []*ServiceInfo

ListServices 列出所有服务

func (*Manager) SetCurrentBinaryPath

func (m *Manager) SetCurrentBinaryPath(path string)

SetCurrentBinaryPath 设置当前二进制文件路径(用于 Detached 模式)

func (*Manager) StartChatService

func (m *Manager) StartChatService(address string, options ...Option) error

StartChatService 启动聊天服务

func (*Manager) StartEmbeddingService

func (m *Manager) StartEmbeddingService(address string, options ...Option) error

StartEmbeddingService 启动嵌入服务

Example

ExampleManager_StartEmbeddingService 演示如何使用管理器启动嵌入服务

// 获取管理器单例
manager := GetManager()

// 启动嵌入服务
err := manager.StartEmbeddingService(
	"127.0.0.1:11434",
	WithModel("Qwen3-Embedding-0.6B-Q4_K_M"),
	WithDebug(true),
	WithModelPath("/tmp/Qwen3-Embedding-0.6B-Q4_K_M.gguf"),
	WithContextSize(4096),
	WithContBatching(true),
	WithBatchSize(1024),
	WithThreads(8),
)
if err != nil {
	fmt.Printf("Failed to start embedding service: %v\n", err)
	return
}

fmt.Println("Embedding service started successfully")

// 等待一段时间
time.Sleep(2 * time.Second)

// 查看服务状态
services := manager.ListServices()
for _, service := range services {
	fmt.Printf("Service: %s, Status: %s\n", service.Name, service.Status)
}

// 停止所有服务
err = manager.StopAllServices()
if err != nil {
	fmt.Printf("Failed to stop services: %v\n", err)
	return
}

fmt.Println("All services stopped")

func (*Manager) StartService

func (m *Manager) StartService(address string, options ...Option) error

StartService 启动服务的通用方法

func (*Manager) StopAllServices

func (m *Manager) StopAllServices() error

StopAllServices 停止所有服务

func (*Manager) StopService

func (m *Manager) StopService(serviceName string) error

StopService 停止指定服务

func (*Manager) WaitForEmbeddingService

func (m *Manager) WaitForEmbeddingService(address string, timeoutSeconds float64) error

WaitForEmbeddingService 等待嵌入服务完全启动并可用

type Model

type Model = ModelConfig

ModelConfig 模型配置

type ModelConfig

type ModelConfig struct {
	Name        string `json:"name"`
	Type        string `json:"type"` // embedding, llm, etc.
	FileName    string `json:"fileName"`
	DownloadURL string `json:"downloadURL"`
	Description string `json:"description"`
	DefaultPort int32  `json:"defaultPort"`
}

ModelConfig 模型配置

func FindModelConfig

func FindModelConfig(modelName string) (*ModelConfig, error)

FindModelConfig 查找模型配置

Example

ExampleFindModelConfig 演示如何查找模型配置

modelName := "Qwen3-Embedding-0.6B-Q4_K_M"

model, err := FindModelConfig(modelName)
if err != nil {
	fmt.Printf("Model not found: %v\n", err)
	return
}

fmt.Printf("Found model: %s\n", model.Name)
fmt.Printf("Type: %s\n", model.Type)
fmt.Printf("Description: %s\n", model.Description)
fmt.Printf("Default Port: %d\n", model.DefaultPort)

func GetChatModels

func GetChatModels() []*ModelConfig

GetChatModels 获取聊天模型列表

func GetDefaultChatModel

func GetDefaultChatModel() *ModelConfig

GetDefaultChatModel 获取默认聊天模型

func GetEmbeddingModels

func GetEmbeddingModels() []*ModelConfig

GetEmbeddingModels 获取嵌入模型列表

func GetModelsByType

func GetModelsByType(modelType string) []*ModelConfig

GetModelsByType 根据类型获取模型列表

func GetSupportedModels

func GetSupportedModels() []*ModelConfig

GetSupportedModels 获取支持的模型列表

Example

ExampleGetSupportedModels 演示如何获取支持的模型列表

models := GetSupportedModels()

fmt.Printf("Supported models (%d):\n", len(models))
for _, model := range models {
	fmt.Printf("- %s (%s): %s\n", model.Name, model.Type, model.Description)
	fmt.Printf("  Default Port: %d\n", model.DefaultPort)
	fmt.Printf("  File: %s\n", model.FileName)
	fmt.Println()
}

type ModelManager

type ModelManager = Manager

Manager 本地模型管理器

type Option

type Option func(*ServiceConfig)

Option 定义选项函数类型

func WithArgs

func WithArgs(args ...string) Option

WithArgs 设置额外的命令行参数

func WithBatchSize

func WithBatchSize(size int) Option

WithBatchSize 设置批处理大小

func WithContBatching

func WithContBatching(enabled bool) Option

WithContBatching 设置是否启用连续批处理

func WithContextSize

func WithContextSize(size int) Option

WithContextSize 设置上下文大小

func WithDebug

func WithDebug(debug bool) Option

WithDebug 设置调试模式

func WithHost

func WithHost(host string) Option

WithHost 设置主机地址

func WithLlamaServerPath

func WithLlamaServerPath(path string) Option

WithLlamaServerPath 设置 llama-server 路径

func WithModel

func WithModel(model string) Option

WithModel 设置模型

func WithModelPath

func WithModelPath(path string) Option

WithModelPath 设置模型路径

func WithModelType

func WithModelType(modelType string) Option

func WithPooling

func WithPooling(pooling string) Option

WithPooling 设置池化方式

func WithPort

func WithPort(port int32) Option

WithPort 设置端口

func WithStartupTimeout

func WithStartupTimeout(timeout time.Duration) Option

WithStartupTimeout 设置启动超时时间

func WithThreads

func WithThreads(threads int) Option

WithThreads 设置线程数

type ProcessInfo

type ProcessInfo struct {
	PID     int
	PPID    int
	Command string
	Args    []string
	WorkDir string
}

ProcessInfo 进程信息结构

type Service

type Service = ServiceInfo

ServiceInfo 服务信息

type ServiceConfig

type ServiceConfig struct {
	Host            string        `json:"host"`
	Port            int32         `json:"port"`
	Model           string        `json:"model"`
	ModelType       string        `json:"modelType"`
	ModelPath       string        `json:"modelPath"`
	LlamaServerPath string        `json:"llamaServerPath"`
	ContextSize     int           `json:"contextSize"`
	ContBatching    bool          `json:"contBatching"` // 连续批处理
	BatchSize       int           `json:"batchSize"`    // 批处理大小
	Threads         int           `json:"threads"`      // 线程数
	Debug           bool          `json:"debug"`
	Pooling         string        `json:"pooling"` // 池化方式
	StartupTimeout  time.Duration `json:"startupTimeout"`
	Args            []string      `json:"args"`
}

ServiceConfig 服务配置

func DefaultServiceConfig

func DefaultServiceConfig() *ServiceConfig

DefaultServiceConfig 返回默认服务配置

type ServiceInfo

type ServiceInfo struct {
	Name      string         `json:"name"`
	Type      ServiceType    `json:"type"`
	Status    ServiceStatus  `json:"status"`
	Config    *ServiceConfig `json:"config"`
	ProcessID int            `json:"processID"`

	StartTime time.Time `json:"startTime"`
	Process   *exec.Cmd `json:"-"`
	LastError string    `json:"lastError,omitempty"`
	// contains filtered or unexported fields
}

ServiceInfo 服务信息

func GetServiceStatus

func GetServiceStatus(serviceName string) (*ServiceInfo, error)

GetServiceStatus 获取服务状态(便捷函数)

func ListServices

func ListServices() []*ServiceInfo

ListServices 列出所有服务(便捷函数)

type ServiceStatus

type ServiceStatus int

ServiceStatus 服务状态

Example

ExampleServiceStatus 演示服务状态

statuses := []ServiceStatus{
	StatusStopped,
	StatusStarting,
	StatusRunning,
	StatusStopping,
	StatusError,
}

fmt.Println("Service status values:")
for _, status := range statuses {
	fmt.Printf("- %d: %s\n", status, status.String())
}
const (
	StatusStopped ServiceStatus = iota
	StatusStarting
	StatusRunning
	StatusStopping
	StatusError
)

func (ServiceStatus) String

func (s ServiceStatus) String() string

type ServiceType

type ServiceType string

ServiceType 服务类型

const (
	ServiceTypeEmbedding ServiceType = "embedding"
	ServiceTypeChat      ServiceType = "aichat"
)

func (ServiceType) String

func (t ServiceType) String() string

type Status

type Status = ServiceStatus

ServiceStatus 服务状态

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL