Skip to content

Commit 2577535

Browse files
committed
Enable loading of lora-adapter parts in dev mode
Signed-off-by: Rishi Jat <rishijat098@gmail.com>
1 parent 925700b commit 2577535

2 files changed

Lines changed: 73 additions & 7 deletions

File tree

pkg/cmd/dev/dev.go

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,25 @@ func runDev(ctx context.Context, options *DevStartOptions) error {
8585
return err
8686
}
8787

88+
// Detect and collect lora-adapter parts
89+
var loraPaths []string
90+
for _, part := range kitfile.Model.Parts {
91+
if strings.EqualFold(part.Type, "lora-adapter") {
92+
partAbsPath, _, err := filesystem.VerifySubpath(options.contextDir, part.Path)
93+
if err != nil {
94+
output.Debugf("Failed to verify lora-adapter path %s: %v", part.Path, err)
95+
continue
96+
}
97+
loraPath, err := findLoraAdapterFile(partAbsPath)
98+
if err != nil {
99+
output.Debugf("Failed to find lora-adapter file in %s: %v", partAbsPath, err)
100+
continue
101+
}
102+
output.Infof("Found lora-adapter: %s", loraPath)
103+
loraPaths = append(loraPaths, loraPath)
104+
}
105+
}
106+
88107
llmHarness := &harness.LLMHarness{}
89108
llmHarness.Host = options.host
90109
llmHarness.Port = options.port
@@ -93,7 +112,7 @@ func runDev(ctx context.Context, options *DevStartOptions) error {
93112
return err
94113
}
95114

96-
if err := llmHarness.Start(modelPath); err != nil {
115+
if err := llmHarness.Start(modelPath, loraPaths); err != nil {
97116
return err
98117
}
99118

@@ -170,6 +189,43 @@ func findModelFile(absPath string) (string, error) {
170189
return modelPath, nil
171190
}
172191

192+
// findLoraAdapterFile finds a lora adapter file (.gguf) within a path.
193+
// If the path is a regular file, it returns that file.
194+
// If the path is a directory, it searches for .gguf files within it.
195+
func findLoraAdapterFile(absPath string) (string, error) {
196+
stat, err := os.Lstat(absPath)
197+
if err != nil {
198+
return "", err
199+
}
200+
if stat.Mode().IsRegular() {
201+
// lora adapter path refers to a regular file; assume it's fine to use
202+
return absPath, nil
203+
} else if !stat.IsDir() {
204+
return "", fmt.Errorf("could not find lora adapter file in %s: path is not regular file or directory", absPath)
205+
}
206+
207+
loraPath := ""
208+
if err := filepath.WalkDir(absPath, func(path string, d fs.DirEntry, err error) error {
209+
if err != nil {
210+
return err
211+
}
212+
if strings.HasSuffix(path, ".gguf") && d.Type().IsRegular() {
213+
if loraPath == "" {
214+
loraPath = path
215+
} else {
216+
return fmt.Errorf("multiple lora adapter files found: %s and %s", loraPath, path)
217+
}
218+
}
219+
return nil
220+
}); err != nil {
221+
return "", fmt.Errorf("error searching for lora adapter file in %s: %w", absPath, err)
222+
} else if loraPath == "" {
223+
return "", fmt.Errorf("could not find lora adapter file in %s", absPath)
224+
}
225+
output.Debugf("Found lora adapter path in directory %s at %s", absPath, loraPath)
226+
return loraPath, nil
227+
}
228+
173229
// extractModelKitToCache extracts a ModelKit reference to a cache directory
174230
// using the unpack library with model filter
175231
func extractModelKitToCache(ctx context.Context, options *DevStartOptions) error {

pkg/lib/harness/llm-harness.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (harness *LLMHarness) Init() error {
6363
return nil
6464
}
6565

66-
func (harness *LLMHarness) Start(modelPath string) (err error) {
66+
func (harness *LLMHarness) Start(modelPath string, loraPaths []string) (err error) {
6767

6868
harnessPath := constants.HarnessPath(harness.ConfigHome)
6969
pidFile := filepath.Join(harnessPath, constants.HarnessProcessFile)
@@ -85,10 +85,12 @@ func (harness *LLMHarness) Start(modelPath string) (err error) {
8585

8686
uiHome := filepath.Join(harnessPath, "ui")
8787
output.Debugf("model path is %s", modelPath)
88+
for _, loraPath := range loraPaths {
89+
output.Debugf("lora adapter path is %s", loraPath)
90+
}
8891
var cmd *exec.Cmd
8992
if runtime.GOOS == "windows" {
90-
cmd = exec.Command(
91-
"./llamafile.exe",
93+
args := []string{
9294
"--server",
9395
"--model", modelPath,
9496
"--host", harness.Host,
@@ -97,11 +99,19 @@ func (harness *LLMHarness) Start(modelPath string) (err error) {
9799
"--gpu", "AUTO",
98100
"--nobrowser",
99101
"--unsecure",
100-
)
102+
}
103+
for _, loraPath := range loraPaths {
104+
args = append(args, "--lora", loraPath)
105+
}
106+
cmd = exec.Command("./llamafile.exe", args...)
101107
} else {
108+
loraArgs := ""
109+
for _, loraPath := range loraPaths {
110+
loraArgs += fmt.Sprintf(" --lora %s", loraPath)
111+
}
102112
cmd = exec.Command("sh", "-c",
103-
fmt.Sprintf("./llamafile --server --model %s --host %s --port %d --path %s --gpu AUTO --nobrowser --unsecure",
104-
modelPath, harness.Host, harness.Port, uiHome),
113+
fmt.Sprintf("./llamafile --server --model %s --host %s --port %d --path %s --gpu AUTO --nobrowser --unsecure%s",
114+
modelPath, harness.Host, harness.Port, uiHome, loraArgs),
105115
)
106116
}
107117

0 commit comments

Comments
 (0)