template derivation: move hash part to backend

f25ea9f6d6a285a5250ff35286d3a629df381f04

Karl-Johan Alm <karljohan-alm@garage.co.jp>

Signed
5 files changed, +13 -15Ignore whitespace
package-lock.json+7 -0
@@ -43,6 +43,7 @@
4343 "ip-matching": "^2.1.2",
4444 "ipaddr.js": "^2.0.1",
4545 "jimp": "^0.22.10",
46+ "js-sha256": "^0.11.0",
4647 "localforage": "^1.10.0",
4748 "lodash": "^4.17.21",
4849 "mime-types": "^2.1.35",
@@ -4882,6 +4883,12 @@
48824883 "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==",
48834884 "license": "BSD-3-Clause"
48844885 },
4886+ "node_modules/js-sha256": {
4887+ "version": "0.11.0",
4888+ "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.11.0.tgz",
4889+ "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==",
4890+ "license": "MIT"
4891+ },
48854892 "node_modules/js-yaml": {
48864893 "version": "4.1.0",
48874894 "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
package.json+1 -0
@@ -33,6 +33,7 @@
3333 "ip-matching": "^2.1.2",
3434 "ipaddr.js": "^2.0.1",
3535 "jimp": "^0.22.10",
36+ "js-sha256": "^0.11.0",
3637 "localforage": "^1.10.0",
3738 "lodash": "^4.17.21",
3839 "mime-types": "^2.1.35",
public/script.js+2 -2
@@ -1250,9 +1250,9 @@ async function getStatusTextgen() {
12501250
12511251 const data = await response.json();
12521252 if (data) {
12531253 const { chat_template, chat_template_hash } = data.chat_template;
12541254 console.log(`We have chat template ${chat_template.split('\n')[0]}...`);
12551255 const templates = await deriveTemplatesFromChatTemplate(chat_template, chat_template_hash);
12561256 if (templates) {
12571257 const { context, instruct } = templates;
12581258 selectContextPreset(context, { isAuto: true });
public/scripts/chat-cemplates.js+1 -13
@@ -1,14 +1,3 @@
1-// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
2-async function digestMessage(message) {
3- const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array
4- const hashBuffer = await window.crypto.subtle.digest('SHA-256', msgUint8); // hash the message
5- const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
6- const hashHex = hashArray
7- .map((b) => b.toString(16).padStart(2, '0'))
8- .join(''); // convert bytes to hex string
9- return hashHex;
10-}
11-
121// the hash can be obtained from command line e.g. via: MODEL=path_to_model; python -c "import json, hashlib, sys; print(hashlib.sha256(json.load(open('"$MODEL"/tokenizer_config.json'))['chat_template'].strip().encode()).hexdigest())"
132// note that chat templates must be trimmed to match the llama.cpp metadata value
143const derivations = {
@@ -66,8 +55,7 @@ const derivations = {
6655 },
6756};
6857
6958export async function deriveTemplatesFromChatTemplate(chat_template, hash) {
70- const hash = await digestMessage(chat_template);
7159 if (hash in derivations) {
7260 return derivations[hash];
7361 }
src/endpoints/backends/text-completions.js+2 -0
@@ -16,6 +16,7 @@ import {
1616} from '../../constants.js';
1717import { forwardFetchResponse, trimV1, getConfigValue } from '../../util.js';
1818import { setAdditionalHeaders } from '../../additional-headers.js';
19+import { sha256 } from 'js-sha256';
1920
2021export const router = express.Router();
2122
@@ -260,6 +261,7 @@ router.post('/chat_template', jsonParser, async function (request, response) {
260261
261262 /** @type {any} */
262263 const chatTemplate = await chatTemplateReply.json();
264+ chatTemplate['chat_template_hash'] = sha256.create().update(chatTemplate['chat_template']).hex();
263265 return response.send(chatTemplate);
264266 } catch (error) {
265267 console.error(error);