Skip to content

Commit f80a342

Browse files
committed
add --mproj to support multimodal model packaging
1 parent cf550f3 commit f80a342

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

cmd/cli/commands/package.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ func newPackagedCmd() *cobra.Command {
2828
var opts packageOptions
2929

3030
c := &cobra.Command{
31-
Use: "package (--gguf <path> | --safetensors-dir <path> | --from <model>) [--license <path>...] [--context-size <tokens>] [--push] MODEL",
31+
Use: "package (--gguf <path> | --safetensors-dir <path> | --from <model>) [--license <path>...] [--mmproj <path>] [--context-size <tokens>] [--push] MODEL",
3232
Short: "Package a GGUF file, Safetensors directory, or existing model into a Docker model OCI artifact.",
33-
Long: "Package a GGUF file, Safetensors directory, or existing model into a Docker model OCI artifact, with optional licenses. The package is sent to the model-runner, unless --push is specified.\n" +
33+
Long: "Package a GGUF file, Safetensors directory, or existing model into a Docker model OCI artifact, with optional licenses and multimodal projector. The package is sent to the model-runner, unless --push is specified.\n" +
3434
"When packaging a sharded GGUF model, --gguf should point to the first shard. All shard files should be siblings and should include the index in the file name (e.g. model-00001-of-00015.gguf).\n" +
3535
"When packaging a Safetensors model, --safetensors-dir should point to a directory containing .safetensors files and config files (*.json, merges.txt). All files will be auto-discovered and config files will be packaged into a tar archive.\n" +
36-
"When packaging from an existing model using --from, you can modify properties like context size to create a variant of the original model.",
36+
"When packaging from an existing model using --from, you can modify properties like context size to create a variant of the original model.\n" +
37+
"For multimodal models, use --mmproj to include a multimodal projector file.",
3738
Args: func(cmd *cobra.Command, args []string) error {
3839
if err := requireExactArgs(1, "package", "MODEL")(cmd, args); err != nil {
3940
return err
@@ -116,6 +117,17 @@ func newPackagedCmd() *cobra.Command {
116117
opts.licensePaths[i] = filepath.Clean(l)
117118
}
118119

120+
// Validate mmproj path if provided
121+
if opts.mmprojPath != "" {
122+
if !filepath.IsAbs(opts.mmprojPath) {
123+
return fmt.Errorf(
124+
"mmproj path must be absolute.\n\n" +
125+
"See 'docker model package --help' for more information",
126+
)
127+
}
128+
opts.mmprojPath = filepath.Clean(opts.mmprojPath)
129+
}
130+
119131
// Validate dir-tar paths are relative (not absolute)
120132
for _, dirPath := range opts.dirTarPaths {
121133
if filepath.IsAbs(dirPath) {
@@ -146,6 +158,7 @@ func newPackagedCmd() *cobra.Command {
146158
c.Flags().StringVar(&opts.chatTemplatePath, "chat-template", "", "absolute path to chat template file (must be Jinja format)")
147159
c.Flags().StringArrayVarP(&opts.licensePaths, "license", "l", nil, "absolute path to a license file")
148160
c.Flags().StringArrayVar(&opts.dirTarPaths, "dir-tar", nil, "relative path to directory to package as tar (can be specified multiple times)")
161+
c.Flags().StringVar(&opts.mmprojPath, "mmproj", "", "absolute path to multimodal projector file")
149162
c.Flags().BoolVar(&opts.push, "push", false, "push to registry (if not set, the model is loaded into the Model Runner content store)")
150163
c.Flags().Uint64Var(&opts.contextSize, "context-size", 0, "context size in tokens")
151164
return c
@@ -159,6 +172,7 @@ type packageOptions struct {
159172
fromModel string
160173
licensePaths []string
161174
dirTarPaths []string
175+
mmprojPath string
162176
push bool
163177
tag string
164178
}
@@ -305,6 +319,14 @@ func packageModel(ctx context.Context, cmd *cobra.Command, client *desktop.Clien
305319
}
306320
}
307321

322+
if opts.mmprojPath != "" {
323+
cmd.PrintErrf("Adding multimodal projector file from %q\n", opts.mmprojPath)
324+
pkg, err = pkg.WithMultimodalProjector(opts.mmprojPath)
325+
if err != nil {
326+
return fmt.Errorf("add multimodal projector file: %w", err)
327+
}
328+
}
329+
308330
// Check if we can use lightweight repackaging (config-only changes from existing model)
309331
useLightweight := opts.fromModel != "" && pkg.HasOnlyConfigChanges()
310332

cmd/cli/docs/reference/docker_model_package.yaml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ command: docker model package
22
short: |
33
Package a GGUF file, Safetensors directory, or existing model into a Docker model OCI artifact.
44
long: |-
5-
Package a GGUF file, Safetensors directory, or existing model into a Docker model OCI artifact, with optional licenses. The package is sent to the model-runner, unless --push is specified.
5+
Package a GGUF file, Safetensors directory, or existing model into a Docker model OCI artifact, with optional licenses and multimodal projector. The package is sent to the model-runner, unless --push is specified.
66
When packaging a sharded GGUF model, --gguf should point to the first shard. All shard files should be siblings and should include the index in the file name (e.g. model-00001-of-00015.gguf).
77
When packaging a Safetensors model, --safetensors-dir should point to a directory containing .safetensors files and config files (*.json, merges.txt). All files will be auto-discovered and config files will be packaged into a tar archive.
88
When packaging from an existing model using --from, you can modify properties like context size to create a variant of the original model.
9-
usage: docker model package (--gguf <path> | --safetensors-dir <path> | --from <model>) [--license <path>...] [--context-size <tokens>] [--push] MODEL
9+
For multimodal models, use --mmproj to include a multimodal projector file.
10+
usage: docker model package (--gguf <path> | --safetensors-dir <path> | --from <model>) [--license <path>...] [--mmproj <path>] [--context-size <tokens>] [--push] MODEL
1011
pname: docker model
1112
plink: docker_model.yaml
1213
options:
@@ -69,6 +70,15 @@ options:
6970
experimentalcli: false
7071
kubernetes: false
7172
swarm: false
73+
- option: mmproj
74+
value_type: string
75+
description: absolute path to multimodal projector file
76+
deprecated: false
77+
hidden: false
78+
experimental: false
79+
experimentalcli: false
80+
kubernetes: false
81+
swarm: false
7282
- option: push
7383
value_type: bool
7484
default_value: "false"

cmd/cli/docs/reference/model_package.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# docker model package
22

33
<!---MARKER_GEN_START-->
4-
Package a GGUF file, Safetensors directory, or existing model into a Docker model OCI artifact, with optional licenses. The package is sent to the model-runner, unless --push is specified.
4+
Package a GGUF file, Safetensors directory, or existing model into a Docker model OCI artifact, with optional licenses and multimodal projector. The package is sent to the model-runner, unless --push is specified.
55
When packaging a sharded GGUF model, --gguf should point to the first shard. All shard files should be siblings and should include the index in the file name (e.g. model-00001-of-00015.gguf).
66
When packaging a Safetensors model, --safetensors-dir should point to a directory containing .safetensors files and config files (*.json, merges.txt). All files will be auto-discovered and config files will be packaged into a tar archive.
77
When packaging from an existing model using --from, you can modify properties like context size to create a variant of the original model.
8+
For multimodal models, use --mmproj to include a multimodal projector file.
89

910
### Options
1011

@@ -16,6 +17,7 @@ When packaging from an existing model using --from, you can modify properties li
1617
| `--from` | `string` | | reference to an existing model to repackage |
1718
| `--gguf` | `string` | | absolute path to gguf file |
1819
| `-l`, `--license` | `stringArray` | | absolute path to a license file |
20+
| `--mmproj` | `string` | | absolute path to multimodal projector file |
1921
| `--push` | `bool` | | push to registry (if not set, the model is loaded into the Model Runner content store) |
2022
| `--safetensors-dir` | `string` | | absolute path to directory containing safetensors files and config |
2123

0 commit comments

Comments
 (0)