Compare commits
6 Commits
main
...
royh-show-
Author | SHA1 | Date | |
---|---|---|---|
|
d63e1f5b34 | ||
|
239a994c47 | ||
|
ebbaa8b513 | ||
|
cdbda76fa9 | ||
|
30f7064363 | ||
|
ccd624ca44 |
16
api/types.go
16
api/types.go
@ -232,13 +232,15 @@ type ShowRequest struct {
|
||||
|
||||
// ShowResponse is the response returned from [Client.Show].
|
||||
type ShowResponse struct {
|
||||
License string `json:"license,omitempty"`
|
||||
Modelfile string `json:"modelfile,omitempty"`
|
||||
Parameters string `json:"parameters,omitempty"`
|
||||
Template string `json:"template,omitempty"`
|
||||
System string `json:"system,omitempty"`
|
||||
Details ModelDetails `json:"details,omitempty"`
|
||||
Messages []Message `json:"messages,omitempty"`
|
||||
License string `json:"license,omitempty"`
|
||||
Modelfile string `json:"modelfile,omitempty"`
|
||||
Parameters string `json:"parameters,omitempty"`
|
||||
Template string `json:"template,omitempty"`
|
||||
System string `json:"system,omitempty"`
|
||||
Details ModelDetails `json:"details,omitempty"`
|
||||
Messages []Message `json:"messages,omitempty"`
|
||||
ModelInfo map[string]any `json:"model_info,omitempty"`
|
||||
// * placing llm.KV creates an import cycle between api and llm...
|
||||
}
|
||||
|
||||
// CopyRequest is the request passed to [Client.Copy].
|
||||
|
140
cmd/cmd.go
140
cmd/cmd.go
@ -579,17 +579,20 @@ func ShowHandler(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
if len(args) == 0 {
|
||||
return errors.New("missing model name")
|
||||
} else if len(args) > 1 {
|
||||
return errors.New("only one model name can be specified")
|
||||
}
|
||||
|
||||
model, errModel := cmd.Flags().GetBool("model")
|
||||
license, errLicense := cmd.Flags().GetBool("license")
|
||||
modelfile, errModelfile := cmd.Flags().GetBool("modelfile")
|
||||
parameters, errParams := cmd.Flags().GetBool("parameters")
|
||||
system, errSystem := cmd.Flags().GetBool("system")
|
||||
template, errTemplate := cmd.Flags().GetBool("template")
|
||||
|
||||
for _, boolErr := range []error{errLicense, errModelfile, errParams, errSystem, errTemplate} {
|
||||
for _, boolErr := range []error{errModel, errLicense, errModelfile, errParams, errSystem, errTemplate} {
|
||||
if boolErr != nil {
|
||||
return errors.New("error retrieving flags")
|
||||
}
|
||||
@ -598,6 +601,11 @@ func ShowHandler(cmd *cobra.Command, args []string) error {
|
||||
flagsSet := 0
|
||||
showType := ""
|
||||
|
||||
if model {
|
||||
flagsSet++
|
||||
showType = "model"
|
||||
}
|
||||
|
||||
if license {
|
||||
flagsSet++
|
||||
showType = "license"
|
||||
@ -623,34 +631,118 @@ func ShowHandler(cmd *cobra.Command, args []string) error {
|
||||
showType = "template"
|
||||
}
|
||||
|
||||
if flagsSet > 1 {
|
||||
return errors.New("only one of '--license', '--modelfile', '--parameters', '--system', or '--template' can be specified")
|
||||
} else if flagsSet == 0 {
|
||||
return errors.New("one of '--license', '--modelfile', '--parameters', '--system', or '--template' must be specified")
|
||||
}
|
||||
switch flagsSet {
|
||||
case 0:
|
||||
req := api.ShowRequest{Name: args[0]}
|
||||
resp, err := client.Show(cmd.Context(), &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req := api.ShowRequest{Name: args[0]}
|
||||
resp, err := client.Show(cmd.Context(), &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var data []string
|
||||
|
||||
switch showType {
|
||||
case "license":
|
||||
fmt.Println(resp.License)
|
||||
case "modelfile":
|
||||
fmt.Println(resp.Modelfile)
|
||||
case "parameters":
|
||||
fmt.Println(resp.Parameters)
|
||||
case "system":
|
||||
fmt.Println(resp.System)
|
||||
case "template":
|
||||
fmt.Println(resp.Template)
|
||||
data = append(data,
|
||||
strings.Join([]string{
|
||||
fmt.Sprintf("arch %v", resp.ModelInfo["general.architecture"]),
|
||||
fmt.Sprintf("parameters %v", resp.Details.ParameterSize),
|
||||
fmt.Sprintf("quantization %v", resp.Details.QuantizationLevel),
|
||||
}, " · "),
|
||||
truncate(resp.License),
|
||||
truncate(resp.Modelfile),
|
||||
handleParams(resp.Parameters),
|
||||
truncate(resp.System),
|
||||
truncate(resp.Template),
|
||||
)
|
||||
|
||||
headers := []string{
|
||||
"MODEL",
|
||||
"LICENSE",
|
||||
"MODELFILE",
|
||||
"PARAMETERS",
|
||||
"SYSTEM",
|
||||
"TEMPLATE",
|
||||
}
|
||||
|
||||
table := tablewriter.NewWriter(os.Stdout)
|
||||
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
|
||||
table.SetAlignment(tablewriter.ALIGN_LEFT)
|
||||
table.SetBorder(false)
|
||||
table.SetNoWhiteSpace(true)
|
||||
table.SetTablePadding("\t")
|
||||
table.SetAutoWrapText(false)
|
||||
for i := range headers {
|
||||
if data[i] != "" {
|
||||
table.Append([]string{headers[i], data[i]})
|
||||
}
|
||||
}
|
||||
table.Render()
|
||||
|
||||
case 1:
|
||||
req := api.ShowRequest{Name: args[0]}
|
||||
resp, err := client.Show(cmd.Context(), &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch showType {
|
||||
case "license":
|
||||
fmt.Println(resp.License)
|
||||
case "modelfile":
|
||||
fmt.Println(resp.Modelfile)
|
||||
case "parameters":
|
||||
fmt.Println(resp.Parameters)
|
||||
case "system":
|
||||
fmt.Println(resp.System)
|
||||
case "template":
|
||||
fmt.Println(resp.Template)
|
||||
case "model":
|
||||
fmt.Println(
|
||||
strings.Join([]string{
|
||||
fmt.Sprintf("arch %v", resp.ModelInfo["general.architecture"]),
|
||||
fmt.Sprintf("parameters %v", resp.Details.ParameterSize),
|
||||
fmt.Sprintf("quantization %v", resp.Details.QuantizationLevel),
|
||||
}, " · "),
|
||||
)
|
||||
}
|
||||
default:
|
||||
return errors.New("only one of '--model', --license', '--modelfile', '--parameters', '--system', or '--template' can be specified")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func truncate(s string) string {
|
||||
lines := strings.Split(s, "\n")
|
||||
var truncated strings.Builder
|
||||
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if line != "" {
|
||||
truncated.WriteString(line + " ")
|
||||
if truncated.Len() > 60 {
|
||||
return truncated.String()[:57] + "..."
|
||||
}
|
||||
}
|
||||
}
|
||||
return strings.TrimSpace(truncated.String())
|
||||
}
|
||||
|
||||
// temporary fix for buggy params #4918
|
||||
func handleParams(s string) string {
|
||||
lines := strings.Split(s, "\n")
|
||||
var truncated strings.Builder
|
||||
|
||||
truncated.WriteString("{")
|
||||
for _, line := range lines {
|
||||
line = strings.Join(strings.Fields(line), ":")
|
||||
truncated.WriteString(line + ",")
|
||||
if truncated.Len() > 60 {
|
||||
return truncated.String()[:57] + "..."
|
||||
}
|
||||
}
|
||||
return strings.TrimSpace(truncated.String()) + "}"
|
||||
}
|
||||
|
||||
func CopyHandler(cmd *cobra.Command, args []string) error {
|
||||
client, err := api.ClientFromEnvironment()
|
||||
if err != nil {
|
||||
@ -1122,11 +1214,11 @@ func NewCLI() *cobra.Command {
|
||||
showCmd := &cobra.Command{
|
||||
Use: "show MODEL",
|
||||
Short: "Show information for a model",
|
||||
Args: cobra.ExactArgs(1),
|
||||
PreRunE: checkServerHeartbeat,
|
||||
RunE: ShowHandler,
|
||||
}
|
||||
|
||||
showCmd.Flags().Bool("model", false, "Show basic stats of a model")
|
||||
showCmd.Flags().Bool("license", false, "Show license of a model")
|
||||
showCmd.Flags().Bool("modelfile", false, "Show Modelfile of a model")
|
||||
showCmd.Flags().Bool("parameters", false, "Show parameters of a model")
|
||||
|
@ -720,9 +720,47 @@ func GetModelInfo(req api.ShowRequest) (*api.ShowResponse, error) {
|
||||
fmt.Fprint(&sb, model.String())
|
||||
resp.Modelfile = sb.String()
|
||||
|
||||
ggmlData, err := getGGMLData(model)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// exclusionList := []string{}
|
||||
// for _, e := range exclusionList {
|
||||
// delete(ggmlData, e)
|
||||
// }
|
||||
|
||||
resp.ModelInfo = ggmlData
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func getGGMLData(model *Model) (llm.KV, error) {
|
||||
f, err := os.Open(model.ModelPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
ggml, _, err := llm.DecodeGGML(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kv := ggml.KV()
|
||||
|
||||
for k := range kv {
|
||||
if t, ok := kv[k].([]any); ok {
|
||||
kv[k] = fmt.Sprintf("... (%d values)", len(t))
|
||||
}
|
||||
}
|
||||
|
||||
// kv["embedding_model"] = model.IsEmbedding()
|
||||
|
||||
return kv, nil
|
||||
}
|
||||
|
||||
func (s *Server) ListModelsHandler(c *gin.Context) {
|
||||
ms, err := Manifests()
|
||||
if err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user