Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
ollama
Commits
e7e91cd7
Unverified
Commit
e7e91cd7
authored
Sep 11, 2023
by
Patrick Devine
Committed by
GitHub
Sep 11, 2023
Browse files
add autoprune to remove unused layers (#491)
parent
3920e153
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
136 additions
and
19 deletions
+136
-19
cmd/cmd.go
cmd/cmd.go
+6
-0
server/images.go
server/images.go
+129
-19
server/routes.go
server/routes.go
+1
-0
No files found.
cmd/cmd.go
View file @
e7e91cd7
...
@@ -672,6 +672,12 @@ func RunServer(cmd *cobra.Command, _ []string) error {
...
@@ -672,6 +672,12 @@ func RunServer(cmd *cobra.Command, _ []string) error {
origins
=
strings
.
Split
(
o
,
","
)
origins
=
strings
.
Split
(
o
,
","
)
}
}
if
noprune
:=
os
.
Getenv
(
"OLLAMA_NOPRUNE"
);
noprune
==
""
{
if
err
:=
server
.
PruneLayers
();
err
!=
nil
{
return
err
}
}
return
server
.
Serve
(
ln
,
origins
)
return
server
.
Serve
(
ln
,
origins
)
}
}
...
...
server/images.go
View file @
e7e91cd7
...
@@ -269,6 +269,29 @@ func filenameWithPath(path, f string) (string, error) {
...
@@ -269,6 +269,29 @@ func filenameWithPath(path, f string) (string, error) {
}
}
func
CreateModel
(
ctx
context
.
Context
,
name
string
,
path
string
,
fn
func
(
resp
api
.
ProgressResponse
))
error
{
func
CreateModel
(
ctx
context
.
Context
,
name
string
,
path
string
,
fn
func
(
resp
api
.
ProgressResponse
))
error
{
mp
:=
ParseModelPath
(
name
)
var
manifest
*
ManifestV2
var
err
error
var
noprune
string
// build deleteMap to prune unused layers
deleteMap
:=
make
(
map
[
string
]
bool
)
if
noprune
=
os
.
Getenv
(
"OLLAMA_NOPRUNE"
);
noprune
==
""
{
manifest
,
_
,
err
=
GetManifest
(
mp
)
if
err
!=
nil
&&
!
errors
.
Is
(
err
,
os
.
ErrNotExist
)
{
return
err
}
if
manifest
!=
nil
{
for
_
,
l
:=
range
manifest
.
Layers
{
deleteMap
[
l
.
Digest
]
=
true
}
deleteMap
[
manifest
.
Config
.
Digest
]
=
true
}
}
mf
,
err
:=
os
.
Open
(
path
)
mf
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
if
err
!=
nil
{
fn
(
api
.
ProgressResponse
{
Status
:
fmt
.
Sprintf
(
"couldn't open modelfile '%s'"
,
path
)})
fn
(
api
.
ProgressResponse
{
Status
:
fmt
.
Sprintf
(
"couldn't open modelfile '%s'"
,
path
)})
...
@@ -506,6 +529,7 @@ func CreateModel(ctx context.Context, name string, path string, fn func(resp api
...
@@ -506,6 +529,7 @@ func CreateModel(ctx context.Context, name string, path string, fn func(resp api
var
manifestLayers
[]
*
Layer
var
manifestLayers
[]
*
Layer
for
_
,
l
:=
range
layers
{
for
_
,
l
:=
range
layers
{
manifestLayers
=
append
(
manifestLayers
,
&
l
.
Layer
)
manifestLayers
=
append
(
manifestLayers
,
&
l
.
Layer
)
delete
(
deleteMap
,
l
.
Layer
.
Digest
)
}
}
// Create a layer for the config object
// Create a layer for the config object
...
@@ -515,6 +539,7 @@ func CreateModel(ctx context.Context, name string, path string, fn func(resp api
...
@@ -515,6 +539,7 @@ func CreateModel(ctx context.Context, name string, path string, fn func(resp api
return
err
return
err
}
}
layers
=
append
(
layers
,
cfg
)
layers
=
append
(
layers
,
cfg
)
delete
(
deleteMap
,
cfg
.
Layer
.
Digest
)
if
err
:=
SaveLayers
(
layers
,
fn
,
false
);
err
!=
nil
{
if
err
:=
SaveLayers
(
layers
,
fn
,
false
);
err
!=
nil
{
return
err
return
err
...
@@ -527,6 +552,14 @@ func CreateModel(ctx context.Context, name string, path string, fn func(resp api
...
@@ -527,6 +552,14 @@ func CreateModel(ctx context.Context, name string, path string, fn func(resp api
return
err
return
err
}
}
if
noprune
==
""
{
fn
(
api
.
ProgressResponse
{
Status
:
"removing any unused layers"
})
err
=
deleteUnusedLayers
(
nil
,
deleteMap
,
false
)
if
err
!=
nil
{
return
err
}
}
fn
(
api
.
ProgressResponse
{
Status
:
"success"
})
fn
(
api
.
ProgressResponse
{
Status
:
"success"
})
return
nil
return
nil
}
}
...
@@ -869,18 +902,7 @@ func CopyModel(src, dest string) error {
...
@@ -869,18 +902,7 @@ func CopyModel(src, dest string) error {
return
nil
return
nil
}
}
func
DeleteModel
(
name
string
)
error
{
func
deleteUnusedLayers
(
skipModelPath
*
ModelPath
,
deleteMap
map
[
string
]
bool
,
dryRun
bool
)
error
{
mp
:=
ParseModelPath
(
name
)
manifest
,
_
,
err
:=
GetManifest
(
mp
)
if
err
!=
nil
{
return
err
}
deleteMap
:=
make
(
map
[
string
]
bool
)
for
_
,
layer
:=
range
manifest
.
Layers
{
deleteMap
[
layer
.
Digest
]
=
true
}
deleteMap
[
manifest
.
Config
.
Digest
]
=
true
fp
,
err
:=
GetManifestPath
()
fp
,
err
:=
GetManifestPath
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -897,14 +919,13 @@ func DeleteModel(name string) error {
...
@@ -897,14 +919,13 @@ func DeleteModel(name string) error {
fmp
:=
ParseModelPath
(
tag
)
fmp
:=
ParseModelPath
(
tag
)
// skip the manifest we're trying to delete
// skip the manifest we're trying to delete
if
mp
.
GetFullTagname
()
==
fmp
.
GetFullTagname
()
{
if
skipModelPath
!=
nil
&&
skipModelPath
.
GetFullTagname
()
==
fmp
.
GetFullTagname
()
{
return
nil
return
nil
}
}
// save (i.e. delete from the deleteMap) any files used in other manifests
// save (i.e. delete from the deleteMap) any files used in other manifests
manifest
,
_
,
err
:=
GetManifest
(
fmp
)
manifest
,
_
,
err
:=
GetManifest
(
fmp
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Printf
(
"skipping file: %s"
,
fp
)
return
nil
return
nil
}
}
...
@@ -928,14 +949,72 @@ func DeleteModel(name string) error {
...
@@ -928,14 +949,72 @@ func DeleteModel(name string) error {
log
.
Printf
(
"couldn't get file path for '%s': %v"
,
k
,
err
)
log
.
Printf
(
"couldn't get file path for '%s': %v"
,
k
,
err
)
continue
continue
}
}
if
err
:=
os
.
Remove
(
fp
);
err
!=
nil
{
if
!
dryRun
{
log
.
Printf
(
"couldn't remove file '%s': %v"
,
fp
,
err
)
if
err
:=
os
.
Remove
(
fp
);
err
!=
nil
{
continue
log
.
Printf
(
"couldn't remove file '%s': %v"
,
fp
,
err
)
continue
}
}
else
{
log
.
Printf
(
"wanted to remove: %s"
,
fp
)
}
}
}
}
}
}
fp
,
err
=
mp
.
GetManifestPath
(
false
)
return
nil
}
func
PruneLayers
()
error
{
deleteMap
:=
make
(
map
[
string
]
bool
)
p
,
err
:=
GetBlobsPath
(
""
)
if
err
!=
nil
{
return
err
}
blobs
,
err
:=
os
.
ReadDir
(
p
)
if
err
!=
nil
{
log
.
Printf
(
"couldn't read dir '%s': %v"
,
p
,
err
)
return
err
}
for
_
,
blob
:=
range
blobs
{
name
:=
blob
.
Name
()
if
runtime
.
GOOS
==
"windows"
{
name
=
strings
.
ReplaceAll
(
name
,
"-"
,
":"
)
}
deleteMap
[
name
]
=
true
}
log
.
Printf
(
"total blobs: %d"
,
len
(
deleteMap
))
err
=
deleteUnusedLayers
(
nil
,
deleteMap
,
false
)
if
err
!=
nil
{
return
err
}
log
.
Printf
(
"total unused blobs removed: %d"
,
len
(
deleteMap
))
return
nil
}
func
DeleteModel
(
name
string
)
error
{
mp
:=
ParseModelPath
(
name
)
manifest
,
_
,
err
:=
GetManifest
(
mp
)
if
err
!=
nil
{
return
err
}
deleteMap
:=
make
(
map
[
string
]
bool
)
for
_
,
layer
:=
range
manifest
.
Layers
{
deleteMap
[
layer
.
Digest
]
=
true
}
deleteMap
[
manifest
.
Config
.
Digest
]
=
true
err
=
deleteUnusedLayers
(
&
mp
,
deleteMap
,
false
)
if
err
!=
nil
{
return
err
}
fp
,
err
:=
mp
.
GetManifestPath
(
false
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -1114,13 +1193,34 @@ func PushModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu
...
@@ -1114,13 +1193,34 @@ func PushModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu
func
PullModel
(
ctx
context
.
Context
,
name
string
,
regOpts
*
RegistryOptions
,
fn
func
(
api
.
ProgressResponse
))
error
{
func
PullModel
(
ctx
context
.
Context
,
name
string
,
regOpts
*
RegistryOptions
,
fn
func
(
api
.
ProgressResponse
))
error
{
mp
:=
ParseModelPath
(
name
)
mp
:=
ParseModelPath
(
name
)
var
manifest
*
ManifestV2
var
err
error
var
noprune
string
// build deleteMap to prune unused layers
deleteMap
:=
make
(
map
[
string
]
bool
)
if
noprune
=
os
.
Getenv
(
"OLLAMA_NOPRUNE"
);
noprune
==
""
{
manifest
,
_
,
err
=
GetManifest
(
mp
)
if
err
!=
nil
&&
!
errors
.
Is
(
err
,
os
.
ErrNotExist
)
{
return
err
}
if
manifest
!=
nil
{
for
_
,
l
:=
range
manifest
.
Layers
{
deleteMap
[
l
.
Digest
]
=
true
}
deleteMap
[
manifest
.
Config
.
Digest
]
=
true
}
}
if
mp
.
ProtocolScheme
==
"http"
&&
!
regOpts
.
Insecure
{
if
mp
.
ProtocolScheme
==
"http"
&&
!
regOpts
.
Insecure
{
return
fmt
.
Errorf
(
"insecure protocol http"
)
return
fmt
.
Errorf
(
"insecure protocol http"
)
}
}
fn
(
api
.
ProgressResponse
{
Status
:
"pulling manifest"
})
fn
(
api
.
ProgressResponse
{
Status
:
"pulling manifest"
})
manifest
,
err
:
=
pullModelManifest
(
ctx
,
mp
,
regOpts
)
manifest
,
err
=
pullModelManifest
(
ctx
,
mp
,
regOpts
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"pull model manifest: %s"
,
err
)
return
fmt
.
Errorf
(
"pull model manifest: %s"
,
err
)
}
}
...
@@ -1140,7 +1240,9 @@ func PullModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu
...
@@ -1140,7 +1240,9 @@ func PullModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu
});
err
!=
nil
{
});
err
!=
nil
{
return
err
return
err
}
}
delete
(
deleteMap
,
layer
.
Digest
)
}
}
delete
(
deleteMap
,
manifest
.
Config
.
Digest
)
fn
(
api
.
ProgressResponse
{
Status
:
"verifying sha256 digest"
})
fn
(
api
.
ProgressResponse
{
Status
:
"verifying sha256 digest"
})
for
_
,
layer
:=
range
layers
{
for
_
,
layer
:=
range
layers
{
...
@@ -1178,6 +1280,14 @@ func PullModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu
...
@@ -1178,6 +1280,14 @@ func PullModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu
return
err
return
err
}
}
if
noprune
==
""
{
fn
(
api
.
ProgressResponse
{
Status
:
"removing any unused layers"
})
err
=
deleteUnusedLayers
(
nil
,
deleteMap
,
false
)
if
err
!=
nil
{
return
err
}
}
fn
(
api
.
ProgressResponse
{
Status
:
"success"
})
fn
(
api
.
ProgressResponse
{
Status
:
"success"
})
return
nil
return
nil
...
...
server/routes.go
View file @
e7e91cd7
...
@@ -363,6 +363,7 @@ func DeleteModelHandler(c *gin.Context) {
...
@@ -363,6 +363,7 @@ func DeleteModelHandler(c *gin.Context) {
}
}
return
return
}
}
c
.
JSON
(
http
.
StatusOK
,
nil
)
}
}
func
ShowModelHandler
(
c
*
gin
.
Context
)
{
func
ShowModelHandler
(
c
*
gin
.
Context
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment