Compare commits

...

2 Commits

Author SHA1 Message Date
jmorganca
5dc20e91d0 simplify 2026-01-19 16:15:15 -08:00
jmorganca
bda8cb7403 cmd: auto-detect image generation models during create
Remove the --experimental flag requirement for creating image generation
models. Now ollama create automatically detects imagegen models by checking
for model_index.json in the model directory and routes them to the direct
creation path.

This simplifies the workflow for creating FLUX and other diffusion models -
users no longer need to pass --experimental.
2026-01-19 15:23:09 -08:00
2 changed files with 44 additions and 74 deletions

View File

@@ -101,67 +101,6 @@ func CreateHandler(cmd *cobra.Command, args []string) error {
return fmt.Errorf("invalid model name: %s", modelName)
}
// Check for --experimental flag for safetensors model creation
experimental, _ := cmd.Flags().GetBool("experimental")
if experimental {
// Get Modelfile content - either from -f flag or default to "FROM ."
var reader io.Reader
filename, err := getModelfileName(cmd)
if os.IsNotExist(err) || filename == "" {
// No Modelfile specified or found - use default
reader = strings.NewReader("FROM .\n")
} else if err != nil {
return err
} else {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
reader = f
}
// Parse the Modelfile
modelfile, err := parser.ParseFile(reader)
if err != nil {
return fmt.Errorf("failed to parse Modelfile: %w", err)
}
// Extract FROM path and configuration
var modelDir string
mfConfig := &xcreateclient.ModelfileConfig{}
for _, cmd := range modelfile.Commands {
switch cmd.Name {
case "model":
modelDir = cmd.Args
case "template":
mfConfig.Template = cmd.Args
case "system":
mfConfig.System = cmd.Args
case "license":
mfConfig.License = cmd.Args
}
}
if modelDir == "" {
modelDir = "."
}
// Resolve relative paths based on Modelfile location
if !filepath.IsAbs(modelDir) && filename != "" {
modelDir = filepath.Join(filepath.Dir(filename), modelDir)
}
quantize, _ := cmd.Flags().GetString("quantize")
return xcreateclient.CreateModel(xcreateclient.CreateOptions{
ModelName: modelName,
ModelDir: modelDir,
Quantize: quantize,
Modelfile: mfConfig,
}, p)
}
var reader io.Reader
filename, err := getModelfileName(cmd)
@@ -197,6 +136,28 @@ func CreateHandler(cmd *cobra.Command, args []string) error {
return err
}
// Check if this is a tensor model (image generation) and handle it directly
quantize, _ := cmd.Flags().GetString("quantize")
modelDir := filepath.Dir(filename)
for _, cmd := range modelfile.Commands {
if cmd.Name == "model" {
if filepath.IsAbs(cmd.Args) {
modelDir = cmd.Args
} else {
modelDir = filepath.Join(filepath.Dir(filename), cmd.Args)
}
break
}
}
if create.IsTensorModelDir(modelDir) {
return xcreateclient.CreateModel(xcreateclient.CreateOptions{
ModelName: modelName,
ModelDir: modelDir,
Quantize: quantize,
Modelfile: xcreateclient.ExtractModelfileConfig(modelfile),
}, p)
}
status := "gathering model components"
spinner := progress.NewSpinner(status)
p.Add(status, spinner)
@@ -208,7 +169,6 @@ func CreateHandler(cmd *cobra.Command, args []string) error {
spinner.Stop()
req.Model = modelName
quantize, _ := cmd.Flags().GetString("quantize")
if quantize != "" {
req.Quantize = quantize
}
@@ -1815,22 +1775,15 @@ func NewCLI() *cobra.Command {
rootCmd.Flags().BoolP("version", "v", false, "Show version information")
createCmd := &cobra.Command{
Use: "create MODEL",
Short: "Create a model",
Args: cobra.ExactArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error {
// Skip server check for experimental mode (writes directly to disk)
if experimental, _ := cmd.Flags().GetBool("experimental"); experimental {
return nil
}
return checkServerHeartbeat(cmd, args)
},
RunE: CreateHandler,
Use: "create MODEL",
Short: "Create a model",
Args: cobra.ExactArgs(1),
PreRunE: checkServerHeartbeat,
RunE: CreateHandler,
}
createCmd.Flags().StringP("file", "f", "", "Name of the Modelfile (default \"Modelfile\")")
createCmd.Flags().StringP("quantize", "q", "", "Quantize model to this level (e.g. q4_K_M)")
createCmd.Flags().Bool("experimental", false, "Enable experimental safetensors model creation")
showCmd := &cobra.Command{
Use: "show MODEL",

View File

@@ -12,6 +12,7 @@ import (
"fmt"
"io"
"github.com/ollama/ollama/parser"
"github.com/ollama/ollama/progress"
"github.com/ollama/ollama/server"
"github.com/ollama/ollama/types/model"
@@ -280,3 +281,19 @@ func createModelfileLayers(mf *ModelfileConfig) ([]server.Layer, error) {
return layers, nil
}
// ExtractModelfileConfig extracts template, system, and license from a parsed Modelfile.
func ExtractModelfileConfig(modelfile *parser.Modelfile) *ModelfileConfig {
mfConfig := &ModelfileConfig{}
for _, cmd := range modelfile.Commands {
switch cmd.Name {
case "template":
mfConfig.Template = cmd.Args
case "system":
mfConfig.System = cmd.Args
case "license":
mfConfig.License = cmd.Args
}
}
return mfConfig
}