ember.cpp 0.1.0
C++ inference engine for Llama-family and paperkiln models (CPU, CUDA, WebAssembly)
Loading...
Searching...
No Matches
microtorch::chat::detail Namespace Reference

Functions

std::string dump_py (const json &x)
 
std::string jstr (const std::string &s)
 
std::string go (const std::string &s)
 
void paperkiln_only (const Template &t, const char *what)
 
std::string jinja_tools (const Template &t)
 
std::string modelfile_tools (const std::string &gguf_name, const Template &t)
 
std::string sha256_hex (const std::string &msg)
 

Function Documentation

◆ dump_py()

std::string microtorch::chat::detail::dump_py ( const json &  x)
inline

Definition at line 547 of file chat_template.h.

547 {
548 if (x.is_object()) {
549 std::string s = "{";
550 bool first = true;
551 for (auto it = x.begin(); it != x.end(); ++it) {
552 if (!first) s += ", ";
553 first = false;
554 s += json(it.key()).dump() + ": " + dump_py(it.value());
555 }
556 return s + "}";
557 }
558 if (x.is_array()) {
559 std::string s = "[";
560 for (size_t i = 0; i < x.size(); ++i) s += (i ? ", " : "") + dump_py(x[i]);
561 return s + "]";
562 }
563 if (x.is_number_float())
564 throw Error("a tool definition holds a non-integer number (refused: its text is not portable)");
565 return x.dump();
566}
size_t j
std::string dump_py(const json &x)
nlohmann::json json
Definition server.cpp:68

References dump_py(), and j.

Referenced by dump_py(), and microtorch::chat::tool_json().

◆ go()

std::string microtorch::chat::detail::go ( const std::string &  s)
inline

Definition at line 743 of file chat_template.h.

743 {
744 std::string o;
745 for (size_t i = 0; i < s.size(); ++i) {
746 if (s.compare(i, 2, "{{") == 0) {
747 o += "{{ \"{{\" }}";
748 ++i;
749 } else {
750 o += s[i];
751 }
752 }
753 return o;
754}

References go(), and j.

Referenced by go(), and modelfile_tools().

◆ jinja_tools()

std::string microtorch::chat::detail::jinja_tools ( const Template &  t)
inline

Definition at line 764 of file chat_template.h.

764 {
765 std::string j;
766 if (!t.bos.empty()) j += "{{- " + jstr(t.bos) + " -}}";
767 j += "{%- if messages and messages[0]['role'] == 'system' -%}"
768 "{%- set sys = messages[0]['content'] -%}{%- set msgs = messages[1:] -%}"
769 "{%- else -%}{%- set sys = none -%}{%- set msgs = messages -%}{%- endif -%}";
770 if (t.has_tools)
771 j += "{%- if tools -%}{%- set ns = namespace(d='') -%}{%- for x in tools -%}"
772 "{%- if not loop.first -%}{%- set ns.d = ns.d + " + jstr(t.tools_sep) + " -%}{%- endif -%}"
773 "{%- set ns.d = ns.d + (x | tojson) -%}{%- endfor -%}"
774 "{%- if sys -%}{%- set sys = sys + " + jstr(t.tools_join) + " + ns.d -%}"
775 "{%- else -%}{%- set sys = ns.d -%}{%- endif -%}{%- endif -%}";
776 j += "{%- if sys is not none -%}{{- " + jstr(t.system_open) + " + sys + " + jstr(t.system_close) +
777 " -}}{%- endif -%}";
778 j += "{%- for m in msgs -%}"
779 "{%- if m['role'] == 'user' -%}{{- " + jstr(t.user_open) + " + m['content'] + " + jstr(t.user_close) + " -}}"
780 "{%- elif m['role'] == 'assistant' -%}{{- " + jstr(t.assistant_open) + " + m['content'] -}}"
781 "{%- for c in (m['tool_calls'] or []) -%}{{- " + jstr(t.tool_call_open) + " + c['function']['name'] + " +
782 jstr(t.tool_call_join) + " -}}"
783 "{%- if c['function']['arguments'] is string -%}{{- c['function']['arguments'] -}}"
784 "{%- else -%}{{- c['function']['arguments'] | tojson -}}{%- endif -%}{%- endfor -%}"
785 "{{- " + jstr(t.assistant_close) + " -}}"
786 "{%- elif m['role'] == 'tool' -%}{{- " + jstr(t.tool_open) + " + m['content'] + " + jstr(t.tool_close) + " -}}"
787 "{%- else -%}{{ raise_exception('roles: one leading system message, then user, assistant and tool') }}"
788 "{%- endif -%}{%- endfor -%}"
789 "{%- if add_generation_prompt -%}{{- " + jstr(t.generation_prompt) + " -}}{%- endif -%}";
790 return j;
791}
std::string jstr(const std::string &s)

References j, jinja_tools(), and jstr().

Referenced by jinja_tools().

◆ jstr()

std::string microtorch::chat::detail::jstr ( const std::string &  s)
inline

Definition at line 733 of file chat_template.h.

733 {
734 std::string o = "'";
735 for (char c : s) {
736 if (c == '\\') o += "\\\\";
737 else if (c == '\'') o += "\\'";
738 else if (c == '\n') o += "\\n";
739 else o += c;
740 }
741 return o + "'";
742}
float c

References c, j, and jstr().

Referenced by jinja_tools(), and jstr().

◆ modelfile_tools()

std::string microtorch::chat::detail::modelfile_tools ( const std::string &  gguf_name,
const Template &  t 
)
inline

Definition at line 794 of file chat_template.h.

794 {
795 std::string head = go(t.bos);
796 head += "{{ if or .System .Tools }}" + go(t.system_open) + "{{ if .System }}{{ .System }}{{ end }}"
797 "{{ if .Tools }}{{ if .System }}" + go(t.tools_join) + "{{ end }}"
798 "{{ range $i, $t := .Tools }}{{ if $i }}" + go(t.tools_sep) + "{{ end }}{{ json $t }}{{ end }}"
799 "{{ end }}" + go(t.system_close) + "{{ end }}";
800 const std::string msgs =
801 "{{ range .Messages }}{{ if eq .Role \"user\" }}" + go(t.user_open) + "{{ .Content }}" + go(t.user_close) +
802 "{{ else if eq .Role \"assistant\" }}" + go(t.assistant_open) + "{{ .Content }}"
803 "{{ range .ToolCalls }}" + go(t.tool_call_open) + "{{ .Function.Name }}" + go(t.tool_call_join) +
804 "{{ json .Function.Arguments }}{{ end }}" + go(t.assistant_close) +
805 "{{ else if eq .Role \"tool\" }}" + go(t.tool_open) + "{{ .Content }}" + go(t.tool_close) +
806 "{{ end }}{{ end }}" + go(t.generation_prompt);
807 std::string s = "# Ollama Modelfile for " + gguf_name + ": chat template " + t.id() +
808 " (LOCAL_LLM_STACK.md section 3, point 3).\nFROM ./" + gguf_name + "\nTEMPLATE \"\"\"" + head +
809 msgs + "\"\"\"\n";
810 std::vector<std::string> stops = t.stop_eos;
811 stops.insert(stops.end(), t.stop_turn.begin(), t.stop_turn.end());
812 for (const auto& x : stops) s += "PARAMETER stop " + json(x).dump() + "\n";
813 return s;
814}
std::string go(const std::string &s)
nlohmann::ordered_json json

References go(), j, and modelfile_tools().

Referenced by modelfile_tools().

◆ paperkiln_only()

void microtorch::chat::detail::paperkiln_only ( const Template &  t,
const char *  what 
)
inline

Definition at line 755 of file chat_template.h.

755 {
756 if (t.name != "paperkiln") throw Error(std::string(what) + " writes paperkiln records only");
757}

References j, and paperkiln_only().

Referenced by paperkiln_only().

◆ sha256_hex()

std::string microtorch::chat::detail::sha256_hex ( const std::string &  msg)
inline

Definition at line 871 of file chat_template.h.

871 {
872 static const uint32_t k[64] = {
873 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
874 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
875 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
876 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
877 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
878 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
879 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
880 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
881 uint32_t h[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
882 std::string m = msg;
883 const uint64_t bits = static_cast<uint64_t>(msg.size()) * 8;
884 m += static_cast<char>(0x80);
885 while (m.size() % 64 != 56) m += '\0';
886 for (int i = 7; i >= 0; --i) m += static_cast<char>((bits >> (8 * i)) & 0xff);
887 auto rotr = [](uint32_t x, int n) { return (x >> n) | (x << (32 - n)); };
888 for (size_t off = 0; off < m.size(); off += 64) {
889 uint32_t w[64];
890 for (int i = 0; i < 16; ++i)
891 w[i] = (uint32_t(uint8_t(m[off + 4 * i])) << 24) | (uint32_t(uint8_t(m[off + 4 * i + 1])) << 16) |
892 (uint32_t(uint8_t(m[off + 4 * i + 2])) << 8) | uint32_t(uint8_t(m[off + 4 * i + 3]));
893 for (int i = 16; i < 64; ++i) {
894 const uint32_t s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >> 3);
895 const uint32_t s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >> 10);
896 w[i] = w[i - 16] + s0 + w[i - 7] + s1;
897 }
898 uint32_t a = h[0], b = h[1], c = h[2], d = h[3], e = h[4], f = h[5], g = h[6], hh = h[7];
899 for (int i = 0; i < 64; ++i) {
900 const uint32_t t1 = hh + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + ((e & f) ^ (~e & g)) + k[i] + w[i];
901 const uint32_t t2 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + ((a & b) ^ (a & c) ^ (b & c));
902 hh = g;
903 g = f;
904 f = e;
905 e = d + t1;
906 d = c;
907 c = b;
908 b = a;
909 a = t1 + t2;
910 }
911 h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e; h[5] += f; h[6] += g; h[7] += hh;
912 }
913 char buf[65];
914 for (int i = 0; i < 8; ++i) std::snprintf(buf + 8 * i, 9, "%08x", h[i]);
915 return std::string(buf, 64);
916}
int n
std::vector< E > a

References a, c, j, k, n, off, and sha256_hex().

Referenced by sha256_hex().