|
@@ -105,8 +105,8 @@ func TestTemplate(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
for n, tt := range cases {
|
|
|
+ var actual bytes.Buffer
|
|
|
t.Run(n, func(t *testing.T) {
|
|
|
- var actual bytes.Buffer
|
|
|
if err := tmpl.Execute(&actual, Values{Messages: tt}); err != nil {
|
|
|
t.Fatal(err)
|
|
|
}
|
|
@@ -120,6 +120,25 @@ func TestTemplate(t *testing.T) {
|
|
|
t.Errorf("mismatch (-got +want):\n%s", diff)
|
|
|
}
|
|
|
})
|
|
|
+
|
|
|
+ t.Run("legacy", func(t *testing.T) {
|
|
|
+ var legacy bytes.Buffer
|
|
|
+ if err := tmpl.Execute(&legacy, Values{Messages: tt, forceLegacy: true}); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ legacyBytes := legacy.Bytes()
|
|
|
+ if slices.Contains([]string{"chatqa.gotmpl", "openchat.gotmpl", "vicuna.gotmpl"}, match) && legacyBytes[len(legacyBytes)-1] == ' ' {
|
|
|
+ t.Log("removing trailing space from legacy output")
|
|
|
+ legacyBytes = legacyBytes[:len(legacyBytes)-1]
|
|
|
+ } else if slices.Contains([]string{"codellama-70b-instruct.gotmpl", "llama2-chat.gotmpl", "mistral-instruct.gotmpl"}, match) {
|
|
|
+ t.Skip("legacy outputs cannot be compared to messages outputs")
|
|
|
+ }
|
|
|
+
|
|
|
+ if diff := cmp.Diff(legacyBytes, actual.Bytes()); diff != "" {
|
|
|
+ t.Errorf("mismatch (-got +want):\n%s", diff)
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
})
|
|
|
}
|
|
@@ -136,6 +155,21 @@ func TestParse(t *testing.T) {
|
|
|
{"{{ with .Tools }}{{ . }}{{ end }} {{ .System }} {{ .Prompt }}", []string{"prompt", "response", "system", "tools"}},
|
|
|
{"{{ range .Messages }}{{ .Role }} {{ .Content }}{{ end }}", []string{"content", "messages", "role"}},
|
|
|
{"{{ range .Messages }}{{ if eq .Role \"system\" }}SYSTEM: {{ .Content }}{{ else if eq .Role \"user\" }}USER: {{ .Content }}{{ else if eq .Role \"assistant\" }}ASSISTANT: {{ .Content }}{{ end }}{{ end }}", []string{"content", "messages", "role"}},
|
|
|
+ {`{{- if .Messages }}
|
|
|
+{{- if .System }}<|im_start|>system
|
|
|
+{{ .System }}<|im_end|>
|
|
|
+{{ end }}
|
|
|
+{{- range .Messages }}<|im_start|>{{ .Role }}
|
|
|
+{{ .Content }}<|im_end|>
|
|
|
+{{ end }}<|im_start|>assistant
|
|
|
+{{ else -}}
|
|
|
+{{ if .System }}<|im_start|>system
|
|
|
+{{ .System }}<|im_end|>
|
|
|
+{{ end }}{{ if .Prompt }}<|im_start|>user
|
|
|
+{{ .Prompt }}<|im_end|>
|
|
|
+{{ end }}<|im_start|>assistant
|
|
|
+{{ .Response }}<|im_end|>
|
|
|
+{{- end -}}`, []string{"content", "messages", "prompt", "response", "role", "system"}},
|
|
|
}
|
|
|
|
|
|
for _, tt := range cases {
|
|
@@ -145,9 +179,8 @@ func TestParse(t *testing.T) {
|
|
|
t.Fatal(err)
|
|
|
}
|
|
|
|
|
|
- vars := tmpl.Vars()
|
|
|
- if !slices.Equal(tt.vars, vars) {
|
|
|
- t.Errorf("expected %v, got %v", tt.vars, vars)
|
|
|
+ if diff := cmp.Diff(tmpl.Vars(), tt.vars); diff != "" {
|
|
|
+ t.Errorf("mismatch (-got +want):\n%s", diff)
|
|
|
}
|
|
|
})
|
|
|
}
|
|
@@ -170,7 +203,7 @@ func TestExecuteWithMessages(t *testing.T) {
|
|
|
{"no response", `[INST] {{ if .System }}{{ .System }}{{ "\n\n" }}{{ end }}{{ .Prompt }}[/INST] `},
|
|
|
{"response", `[INST] {{ if .System }}{{ .System }}{{ "\n\n" }}{{ end }}{{ .Prompt }}[/INST] {{ .Response }}`},
|
|
|
{"messages", `{{- range $index, $_ := .Messages }}
|
|
|
-{{- if eq .Role "user" }}[INST] {{ if and (eq (len (slice $.Messages $index)) 1) $.System }}{{ $.System }}{{ "\n\n" }}
|
|
|
+{{- if eq .Role "user" }}[INST] {{ if and (eq $index 0) $.System }}{{ $.System }}{{ "\n\n" }}
|
|
|
{{- end }}{{ .Content }}[/INST] {{ else if eq .Role "assistant" }}{{ .Content }}
|
|
|
{{- end }}
|
|
|
{{- end }}`},
|
|
@@ -191,7 +224,7 @@ func TestExecuteWithMessages(t *testing.T) {
|
|
|
{"response", `[INST] {{ if .System }}{{ .System }}{{ "\n\n" }}{{ end }}{{ .Prompt }}[/INST] {{ .Response }}`},
|
|
|
{"messages", `
|
|
|
{{- range $index, $_ := .Messages }}
|
|
|
-{{- if eq .Role "user" }}[INST] {{ if and (eq (len (slice $.Messages $index)) 1) $.System }}{{ $.System }}{{ "\n\n" }}
|
|
|
+{{- if eq .Role "user" }}[INST] {{ if and (eq $index 0) $.System }}{{ $.System }}{{ "\n\n" }}
|
|
|
{{- end }}{{ .Content }}[/INST] {{ else if eq .Role "assistant" }}{{ .Content }}
|
|
|
{{- end }}
|
|
|
{{- end }}`},
|
|
@@ -204,9 +237,9 @@ func TestExecuteWithMessages(t *testing.T) {
|
|
|
{Role: "user", Content: "What is your name?"},
|
|
|
},
|
|
|
},
|
|
|
- `[INST] Hello friend![/INST] Hello human![INST] You are a helpful assistant!
|
|
|
+ `[INST] You are a helpful assistant!
|
|
|
|
|
|
-What is your name?[/INST] `,
|
|
|
+Hello friend![/INST] Hello human![INST] What is your name?[/INST] `,
|
|
|
},
|
|
|
{
|
|
|
"chatml",
|
|
@@ -221,7 +254,7 @@ What is your name?[/INST] `,
|
|
|
`},
|
|
|
{"messages", `
|
|
|
{{- range $index, $_ := .Messages }}
|
|
|
-{{- if and (eq .Role "user") (eq (len (slice $.Messages $index)) 1) $.System }}<|im_start|>system
|
|
|
+{{- if and (eq .Role "user") (eq $index 0) $.System }}<|im_start|>system
|
|
|
{{ $.System }}<|im_end|>{{ "\n" }}
|
|
|
{{- end }}<|im_start|>{{ .Role }}
|
|
|
{{ .Content }}<|im_end|>{{ "\n" }}
|
|
@@ -236,12 +269,12 @@ What is your name?[/INST] `,
|
|
|
{Role: "user", Content: "What is your name?"},
|
|
|
},
|
|
|
},
|
|
|
- `<|im_start|>user
|
|
|
+ `<|im_start|>system
|
|
|
+You are a helpful assistant!<|im_end|>
|
|
|
+<|im_start|>user
|
|
|
Hello friend!<|im_end|>
|
|
|
<|im_start|>assistant
|
|
|
Hello human!<|im_end|>
|
|
|
-<|im_start|>system
|
|
|
-You are a helpful assistant!<|im_end|>
|
|
|
<|im_start|>user
|
|
|
What is your name?<|im_end|>
|
|
|
<|im_start|>assistant
|
|
@@ -300,8 +333,8 @@ Answer: `,
|
|
|
t.Fatal(err)
|
|
|
}
|
|
|
|
|
|
- if b.String() != tt.expected {
|
|
|
- t.Errorf("expected\n%s,\ngot\n%s", tt.expected, b.String())
|
|
|
+ if diff := cmp.Diff(b.String(), tt.expected); diff != "" {
|
|
|
+ t.Errorf("mismatch (-got +want):\n%s", diff)
|
|
|
}
|
|
|
})
|
|
|
}
|