Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +3 -0
- llama.cpp/models/templates/Apertus-8B-Instruct.jinja +327 -0
- llama.cpp/models/templates/ByteDance-Seed-OSS.jinja +171 -0
- llama.cpp/models/templates/CohereForAI-c4ai-command-r-plus-tool_use.jinja +202 -0
- llama.cpp/models/templates/CohereForAI-c4ai-command-r7b-12-2024-tool_use.jinja +156 -0
- llama.cpp/models/templates/GLM-4.6.jinja +106 -0
- llama.cpp/models/templates/Kimi-K2-Instruct.jinja +60 -0
- llama.cpp/models/templates/Kimi-K2-Thinking.jinja +108 -0
- llama.cpp/models/templates/MiMo-VL.jinja +54 -0
- llama.cpp/models/templates/MiniMax-M2.jinja +159 -0
- llama.cpp/models/templates/deepseek-ai-DeepSeek-R1-Distill-Llama-8B.jinja +1 -0
- llama.cpp/models/templates/deepseek-ai-DeepSeek-R1-Distill-Qwen-32B.jinja +1 -0
- llama.cpp/models/templates/deepseek-ai-DeepSeek-V3.1.jinja +3 -0
- llama.cpp/models/templates/fireworks-ai-llama-3-firefunction-v2.jinja +57 -0
- llama.cpp/models/templates/google-gemma-2-2b-it.jinja +4 -0
- llama.cpp/models/templates/ibm-granite-granite-3.3-2B-Instruct.jinja +59 -0
- llama.cpp/models/templates/llama-cpp-deepseek-r1.jinja +76 -0
- llama.cpp/models/templates/llama-cpp-lfm2.jinja +37 -0
- llama.cpp/models/templates/llama-cpp-rwkv-world.jinja +34 -0
- llama.cpp/models/templates/meetkai-functionary-medium-v3.1.jinja +58 -0
- llama.cpp/models/templates/meetkai-functionary-medium-v3.2.jinja +287 -0
- llama.cpp/models/templates/meta-llama-Llama-3.1-8B-Instruct.jinja +109 -0
- llama.cpp/models/templates/meta-llama-Llama-3.2-3B-Instruct.jinja +93 -0
- llama.cpp/models/templates/meta-llama-Llama-3.3-70B-Instruct.jinja +109 -0
- llama.cpp/models/templates/microsoft-Phi-3.5-mini-instruct.jinja +8 -0
- llama.cpp/pocs/vdot/CMakeLists.txt +9 -0
- llama.cpp/pocs/vdot/q8dot.cpp +173 -0
- llama.cpp/pocs/vdot/vdot.cpp +311 -0
- llama.cpp/scripts/apple/validate-apps.sh +5 -0
- llama.cpp/scripts/apple/validate-ios.sh +820 -0
- llama.cpp/scripts/apple/validate-macos.sh +781 -0
- llama.cpp/scripts/apple/validate-tvos.sh +813 -0
- llama.cpp/scripts/apple/validate-visionos.sh +811 -0
- llama.cpp/scripts/jinja/jinja-tester.py +504 -0
- llama.cpp/scripts/jinja/requirements.txt +2 -0
- llama.cpp/scripts/snapdragon/adb/llama-cli.farf +1 -0
- llama.cpp/scripts/snapdragon/adb/run-bench.sh +52 -0
- llama.cpp/scripts/snapdragon/adb/run-cli.sh +59 -0
- llama.cpp/scripts/snapdragon/adb/run-completion.sh +59 -0
- llama.cpp/scripts/snapdragon/adb/run-mtmd.sh +68 -0
- llama.cpp/scripts/snapdragon/adb/run-tool.sh +54 -0
- llama.cpp/scripts/snapdragon/qdc/readme.md +1 -0
- llama.cpp/scripts/snapdragon/qdc/requirements.txt +25 -0
- llama.cpp/scripts/snapdragon/qdc/tests/test_bench.py +63 -0
- llama.cpp/scripts/snapdragon/windows/run-bench.ps1 +40 -0
- llama.cpp/scripts/snapdragon/windows/run-cli.ps1 +53 -0
- llama.cpp/scripts/snapdragon/windows/run-tool.ps1 +56 -0
- llama.cpp/scripts/snapdragon/windows/setup-build.ps1 +105 -0
- llama.cpp/src/models/afmoe.cpp +191 -0
- llama.cpp/src/models/apertus.cpp +125 -0
.gitattributes
CHANGED
|
@@ -76,3 +76,6 @@ llama.cpp/models/ggml-vocab-qwen2.gguf filter=lfs diff=lfs merge=lfs -text
|
|
| 76 |
llama.cpp/models/ggml-vocab-refact.gguf filter=lfs diff=lfs merge=lfs -text
|
| 77 |
llama.cpp/models/ggml-vocab-starcoder.gguf filter=lfs diff=lfs merge=lfs -text
|
| 78 |
llama.cpp/tools/mtmd/test-1.jpeg filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
llama.cpp/models/ggml-vocab-refact.gguf filter=lfs diff=lfs merge=lfs -text
|
| 77 |
llama.cpp/models/ggml-vocab-starcoder.gguf filter=lfs diff=lfs merge=lfs -text
|
| 78 |
llama.cpp/tools/mtmd/test-1.jpeg filter=lfs diff=lfs merge=lfs -text
|
| 79 |
+
llama.cpp/tools/server/themes/buttons-top/buttons_top.png filter=lfs diff=lfs merge=lfs -text
|
| 80 |
+
llama.cpp/tools/server/themes/wild/llamapattern.png filter=lfs diff=lfs merge=lfs -text
|
| 81 |
+
llama.cpp/tools/server/themes/wild/wild.png filter=lfs diff=lfs merge=lfs -text
|
llama.cpp/models/templates/Apertus-8B-Instruct.jinja
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- macro render_typescript_type(param_spec, required_params, is_nullable=false) -%}
|
| 2 |
+
{%- if param_spec.type == "array" -%}
|
| 3 |
+
{%- if param_spec['items'] -%}
|
| 4 |
+
{%- if param_spec['items']['type'] == "string" -%}
|
| 5 |
+
{{- "string[]" }}
|
| 6 |
+
{%- elif param_spec['items']['type'] == "number" -%}
|
| 7 |
+
{{- "number[]" }}
|
| 8 |
+
{%- elif param_spec['items']['type'] == "integer" -%}
|
| 9 |
+
{{- "number[]" }}
|
| 10 |
+
{%- elif param_spec['items']['type'] == "boolean" -%}
|
| 11 |
+
{{- "boolean[]" }}
|
| 12 |
+
{%- else -%}
|
| 13 |
+
{%- set inner_type = render_typescript_type(param_spec['items'], required_params) -%}
|
| 14 |
+
{%- if inner_type == "object | object" or inner_type|length > 50 -%}
|
| 15 |
+
{{- "any[]" }}
|
| 16 |
+
{%- else -%}
|
| 17 |
+
{{- inner_type + "[]" }}
|
| 18 |
+
{%- endif -%}
|
| 19 |
+
{%- endif -%}
|
| 20 |
+
{%- if param_spec.nullable -%}
|
| 21 |
+
{{- " | null" }}
|
| 22 |
+
{%- endif -%}
|
| 23 |
+
{%- else -%}
|
| 24 |
+
{{- "any[]" }}
|
| 25 |
+
{%- if param_spec.nullable -%}
|
| 26 |
+
{{- " | null" }}
|
| 27 |
+
{%- endif -%}
|
| 28 |
+
{%- endif -%}
|
| 29 |
+
{%- elif param_spec.type is defined and param_spec.type is iterable and param_spec.type is not string and param_spec.type is not mapping and param_spec.type[0] is defined -%}
|
| 30 |
+
{#- Handle array of types like ["object", "object"] from Union[dict, list] #}
|
| 31 |
+
{%- if param_spec.type | length > 1 -%}
|
| 32 |
+
{{- param_spec.type | join(" | ") }}
|
| 33 |
+
{%- else -%}
|
| 34 |
+
{{- param_spec.type[0] }}
|
| 35 |
+
{%- endif -%}
|
| 36 |
+
{%- elif param_spec.oneOf -%}
|
| 37 |
+
{#- Handle oneOf schemas - check for complex unions and fallback to any #}
|
| 38 |
+
{%- set has_object_variants = false -%}
|
| 39 |
+
{%- for variant in param_spec.oneOf -%}
|
| 40 |
+
{%- if variant.type == "object" -%}
|
| 41 |
+
{%- set has_object_variants = true -%}
|
| 42 |
+
{%- endif -%}
|
| 43 |
+
{%- endfor -%}
|
| 44 |
+
{%- if has_object_variants and param_spec.oneOf|length > 1 -%}
|
| 45 |
+
{{- "any" }}
|
| 46 |
+
{%- else -%}
|
| 47 |
+
{%- for variant in param_spec.oneOf -%}
|
| 48 |
+
{{- render_typescript_type(variant, required_params) -}}
|
| 49 |
+
{%- if variant.description %}
|
| 50 |
+
{{- "// " + variant.description }}
|
| 51 |
+
{%- endif -%}
|
| 52 |
+
{%- if variant.default is defined %}
|
| 53 |
+
{{ "// default: " + variant.default|tojson }}
|
| 54 |
+
{%- endif -%}
|
| 55 |
+
{%- if not loop.last %}
|
| 56 |
+
{{- " | " }}
|
| 57 |
+
{% endif -%}
|
| 58 |
+
{%- endfor -%}
|
| 59 |
+
{%- endif -%}
|
| 60 |
+
{%- elif param_spec.type == "string" -%}
|
| 61 |
+
{%- if param_spec.enum -%}
|
| 62 |
+
{{- '"' + param_spec.enum|join('" | "') + '"' -}}
|
| 63 |
+
{%- else -%}
|
| 64 |
+
{{- "string" }}
|
| 65 |
+
{%- if param_spec.nullable %}
|
| 66 |
+
{{- " | null" }}
|
| 67 |
+
{%- endif -%}
|
| 68 |
+
{%- endif -%}
|
| 69 |
+
{%- elif param_spec.type == "number" -%}
|
| 70 |
+
{{- "number" }}
|
| 71 |
+
{%- elif param_spec.type == "integer" -%}
|
| 72 |
+
{{- "number" }}
|
| 73 |
+
{%- elif param_spec.type == "boolean" -%}
|
| 74 |
+
{{- "boolean" }}
|
| 75 |
+
{%- elif param_spec.type == "object" -%}
|
| 76 |
+
{%- if param_spec.properties -%}
|
| 77 |
+
{{- "{\n" }}
|
| 78 |
+
{%- for prop_name, prop_spec in param_spec.properties.items() -%}
|
| 79 |
+
{{- prop_name -}}
|
| 80 |
+
{%- if prop_name not in (param_spec.required or []) -%}
|
| 81 |
+
{{- "?" }}
|
| 82 |
+
{%- endif -%}
|
| 83 |
+
{{- ": " }}
|
| 84 |
+
{{ render_typescript_type(prop_spec, param_spec.required or []) }}
|
| 85 |
+
{%- if not loop.last -%}
|
| 86 |
+
{{-", " }}
|
| 87 |
+
{%- endif -%}
|
| 88 |
+
{%- endfor -%}
|
| 89 |
+
{{- "}" }}
|
| 90 |
+
{%- else -%}
|
| 91 |
+
{{- "object" }}
|
| 92 |
+
{%- endif -%}
|
| 93 |
+
{%- else -%}
|
| 94 |
+
{{- "any" }}
|
| 95 |
+
{%- endif -%}
|
| 96 |
+
{%- endmacro -%}
|
| 97 |
+
|
| 98 |
+
{%- macro render_tools(tools) -%}
|
| 99 |
+
{%- for tool in tools %}
|
| 100 |
+
{{- "// " + tool.description + "\n" }}
|
| 101 |
+
{{- "type "+ tool.name + " = " }}
|
| 102 |
+
{%- if tool.parameters and tool.parameters.properties %}
|
| 103 |
+
{{- "(_: {\n" }}
|
| 104 |
+
{%- for param_name, param_spec in tool.parameters.properties.items() %}
|
| 105 |
+
{%- if param_spec.description %}
|
| 106 |
+
{{- "// " + param_spec.description + "\n" }}
|
| 107 |
+
{%- endif %}
|
| 108 |
+
{{- param_name }}
|
| 109 |
+
{%- if param_name not in (tool.parameters.required or []) -%}
|
| 110 |
+
{{- "?" }}
|
| 111 |
+
{%- endif -%}
|
| 112 |
+
{{- ": " }}
|
| 113 |
+
{{- render_typescript_type(param_spec, tool.parameters.required or []) }}
|
| 114 |
+
{%- if param_spec.default is defined -%}
|
| 115 |
+
{%- if param_spec.enum %}
|
| 116 |
+
{{- ", // default: " + param_spec.default }}
|
| 117 |
+
{%- elif param_spec.oneOf %}
|
| 118 |
+
{{- "// default: " + param_spec.default }}
|
| 119 |
+
{%- else %}
|
| 120 |
+
{{- ", // default: " + param_spec.default|tojson }}
|
| 121 |
+
{%- endif -%}
|
| 122 |
+
{%- endif -%}
|
| 123 |
+
{%- if not loop.last %}
|
| 124 |
+
{{- ",\n" }}
|
| 125 |
+
{%- else %}
|
| 126 |
+
{{- "\n" }}
|
| 127 |
+
{%- endif -%}
|
| 128 |
+
{%- endfor %}
|
| 129 |
+
{{- "}) => any;" }}
|
| 130 |
+
{%- else -%}
|
| 131 |
+
{{- "() => any;" }}
|
| 132 |
+
{%- endif -%}
|
| 133 |
+
{%- if not loop.last -%}
|
| 134 |
+
{{- "\n" }}
|
| 135 |
+
{%- endif -%}
|
| 136 |
+
{%- endfor %}
|
| 137 |
+
{%- endmacro -%}
|
| 138 |
+
|
| 139 |
+
{{ bos_token }}
|
| 140 |
+
|
| 141 |
+
{%- set system_token = '<|system_start|>' -%}
|
| 142 |
+
{%- set end_system_token = '<|system_end|>' -%}
|
| 143 |
+
{%- set developer_token = '<|developer_start|>' -%}
|
| 144 |
+
{%- set end_developer_token = '<|developer_end|>' -%}
|
| 145 |
+
{%- set user_token = '<|user_start|>' -%}
|
| 146 |
+
{%- set end_user_token = '<|user_end|>' -%}
|
| 147 |
+
{%- set assistant_token = '<|assistant_start|>' -%}
|
| 148 |
+
{%- set end_assistant_token = '<|assistant_end|>' -%}
|
| 149 |
+
{%- set inner_token = '<|inner_prefix|>' -%}
|
| 150 |
+
{%- set outer_token = '<|inner_suffix|>' -%}
|
| 151 |
+
{%- set tool_calls_token = '<|tools_prefix|>' -%}
|
| 152 |
+
{%- set end_tool_calls_token = '<|tools_suffix|>' -%}
|
| 153 |
+
|
| 154 |
+
{%- set ns = namespace(in_assistant=false, in_tool=false, in_inner=false, assistant_format=none) -%}
|
| 155 |
+
|
| 156 |
+
{%- if messages and messages[0].role == 'system' -%}
|
| 157 |
+
{%- if "content" in messages[0] -%}
|
| 158 |
+
{%- if messages[0].content is string -%}
|
| 159 |
+
{{ system_token + messages[0].content + end_system_token }}
|
| 160 |
+
{%- elif messages[0].content is mapping and "text" in messages[0].content -%}
|
| 161 |
+
{{ system_token + messages[0].content.text + end_system_token }}
|
| 162 |
+
{%- else -%}
|
| 163 |
+
{{- raise_exception("Invalid system message") -}}
|
| 164 |
+
{%- endif -%}
|
| 165 |
+
{%- else -%}
|
| 166 |
+
{{- raise_exception("Invalid system message") -}}
|
| 167 |
+
{%- endif -%}
|
| 168 |
+
{%- set loop_messages = messages[1:] -%}
|
| 169 |
+
{%- else -%}
|
| 170 |
+
{{ system_token + 'You are Apertus, a helpful assistant created by the SwissAI initiative.\nKnowledge cutoff: 2024-04\nCurrent date: ' + strftime_now('%Y-%m-%d') + end_system_token }}
|
| 171 |
+
{%- set loop_messages = messages -%}
|
| 172 |
+
{%- endif -%}
|
| 173 |
+
|
| 174 |
+
{{ developer_token + 'Deliberation: ' }}
|
| 175 |
+
{%- if enable_thinking is defined and enable_thinking -%}
|
| 176 |
+
{{ 'enabled\n' }}
|
| 177 |
+
{%- else -%}
|
| 178 |
+
{{ 'disabled\n' }}
|
| 179 |
+
{%- endif -%}
|
| 180 |
+
{%- if tools is defined and tools -%}
|
| 181 |
+
{{ 'Tool Capabilities:\n' + render_tools(tools) }}
|
| 182 |
+
{%- else -%}
|
| 183 |
+
{{ 'Tool Capabilities: disabled' }}
|
| 184 |
+
{%- endif -%}
|
| 185 |
+
{{ end_developer_token }}
|
| 186 |
+
|
| 187 |
+
{%- for message in loop_messages -%}
|
| 188 |
+
{%- if message.role == 'user' -%}
|
| 189 |
+
{%- set ns.in_inner = false -%}
|
| 190 |
+
{%- if ns.in_tool -%}
|
| 191 |
+
{{ ']' }}
|
| 192 |
+
{%- set ns.in_tool = false -%}
|
| 193 |
+
{%- endif -%}
|
| 194 |
+
{%- if ns.in_assistant -%}
|
| 195 |
+
{{ end_assistant_token }}
|
| 196 |
+
{%- set ns.in_assistant = false -%}
|
| 197 |
+
{%- endif -%}
|
| 198 |
+
{%- if "content" in message -%}
|
| 199 |
+
{{ user_token }}
|
| 200 |
+
{%- if message.content is string -%}
|
| 201 |
+
{{ message.content }}
|
| 202 |
+
{%- elif message.content is mapping and "parts" in message.content -%}
|
| 203 |
+
{%- set parts = message.content.parts -%}
|
| 204 |
+
{%- for part in parts -%}
|
| 205 |
+
{%- if part.type == "text" -%}
|
| 206 |
+
{{ part.text }}
|
| 207 |
+
{%- else -%}
|
| 208 |
+
{{- raise_exception("Invalid user part: " + part.type) -}}
|
| 209 |
+
{%- endif -%}
|
| 210 |
+
{%- endfor -%}
|
| 211 |
+
{%- else -%}
|
| 212 |
+
{{- raise_exception("Invalid user message: " + message.role) -}}
|
| 213 |
+
{%- endif -%}
|
| 214 |
+
{{ end_user_token }}
|
| 215 |
+
{%- endif -%}
|
| 216 |
+
{%- elif message.role == 'assistant' -%}
|
| 217 |
+
{%- if not ns.in_assistant -%}
|
| 218 |
+
{{ assistant_token }}
|
| 219 |
+
{%- set ns.in_assistant = true -%}
|
| 220 |
+
{%- endif -%}
|
| 221 |
+
{%- if "content" in message and message.content is not none -%}
|
| 222 |
+
{%- if message.content is string and (ns.assistant_format is none or ns.assistant_format == "string") -%}
|
| 223 |
+
{%- if ns.in_tool -%}
|
| 224 |
+
{{ ']' }}
|
| 225 |
+
{%- set ns.in_tool = false -%}
|
| 226 |
+
{%- endif -%}
|
| 227 |
+
{%- set ns.assistant_format = "string" -%}
|
| 228 |
+
{{ message.content }}
|
| 229 |
+
{%- elif message.content is mapping and "blocks" in message.content and (ns.assistant_format is none or ns.assistant_format == "mapping") -%}
|
| 230 |
+
{%- set ns.assistant_format = "mapping" -%}
|
| 231 |
+
{%- set blocks = message.content.blocks -%}
|
| 232 |
+
{%- for block in blocks -%}
|
| 233 |
+
{%- if block.type == 'thoughts' -%}
|
| 234 |
+
{%- if ns.in_tool -%}
|
| 235 |
+
{{ ']' }}
|
| 236 |
+
{%- set ns.in_tool = false -%}
|
| 237 |
+
{%- endif -%}
|
| 238 |
+
{%- if not ns.in_inner -%}
|
| 239 |
+
{%- set ns.in_inner = true -%}
|
| 240 |
+
{{ inner_token }}
|
| 241 |
+
{%- endif -%}
|
| 242 |
+
{{ block.text }}
|
| 243 |
+
{%- elif block.type == 'tool_calls' -%}
|
| 244 |
+
{%- if ns.in_tool -%}
|
| 245 |
+
{{ ']' }}
|
| 246 |
+
{%- set ns.in_tool = false -%}
|
| 247 |
+
{%- endif -%}
|
| 248 |
+
{%- if ns.in_inner and not loop.first and block.calls|length == 1 and block.calls[0].name == 'display_answers' -%}
|
| 249 |
+
{%- set ns.in_inner = false -%}
|
| 250 |
+
{{ outer_token }}
|
| 251 |
+
{%- endif -%}
|
| 252 |
+
{{ tool_calls_token + '[' }}
|
| 253 |
+
{%- for tool_call in block.calls -%}
|
| 254 |
+
{{- '{"' + tool_call.name + '": ' + tool_call.arguments + '}' }}
|
| 255 |
+
{%- if not loop.last -%}
|
| 256 |
+
{{- ", " }}
|
| 257 |
+
{%- endif -%}
|
| 258 |
+
{%- endfor -%}
|
| 259 |
+
{{ ']' + end_tool_calls_token }}
|
| 260 |
+
{%- elif block.type == 'tool_outputs' -%}
|
| 261 |
+
{%- if ns.in_tool -%}
|
| 262 |
+
{{- raise_exception("Cannot have both tool outputs as separate messages and tool outputs as blocks") -}}
|
| 263 |
+
{%- endif -%}
|
| 264 |
+
{{ '[' }}
|
| 265 |
+
{%- for tool_output in block.outputs -%}
|
| 266 |
+
{{- tool_output.output }}
|
| 267 |
+
{%- if not loop.last -%}
|
| 268 |
+
{{- ", " }}
|
| 269 |
+
{%- endif -%}
|
| 270 |
+
{%- endfor -%}
|
| 271 |
+
{{- ']' }}
|
| 272 |
+
{%- elif block.type == 'response' -%}
|
| 273 |
+
{%- if ns.in_tool -%}
|
| 274 |
+
{{ ']' }}
|
| 275 |
+
{%- set ns.in_tool = false -%}
|
| 276 |
+
{%- endif -%}
|
| 277 |
+
{%- if (not loop.first and ns.in_inner) or (ns.in_assistant and ns.in_inner) -%}
|
| 278 |
+
{%- set ns.in_inner = false -%}
|
| 279 |
+
{{ outer_token }}
|
| 280 |
+
{%- endif -%}
|
| 281 |
+
{{ block.text }}
|
| 282 |
+
{%- else -%}
|
| 283 |
+
{{- raise_exception("Invalid assistant block type: " + block.type) -}}
|
| 284 |
+
{%- endif -%}
|
| 285 |
+
{%- endfor -%}
|
| 286 |
+
{%- else -%}
|
| 287 |
+
{{- raise_exception("Invalid assistant content '" + message.content + "', expected " + ns.assistant_format) -}}
|
| 288 |
+
{%- endif -%}
|
| 289 |
+
{%- elif "tool_calls" not in message -%}
|
| 290 |
+
{{- raise_exception("Invalid assistant message " + message) -}}
|
| 291 |
+
{%- endif -%}
|
| 292 |
+
{%- if "tool_calls" in message and message.tool_calls -%}
|
| 293 |
+
{{ tool_calls_token + '[' }}
|
| 294 |
+
{%- for tool_call in message.tool_calls -%}
|
| 295 |
+
{%- if tool_call.type == 'function' -%}
|
| 296 |
+
{%- set function = tool_call.function -%}
|
| 297 |
+
{{- '{"' + function.name + '": ' + function.arguments + '}' }}
|
| 298 |
+
{%- if not loop.last -%}
|
| 299 |
+
{{- ", " }}
|
| 300 |
+
{%- endif -%}
|
| 301 |
+
{%- else -%}
|
| 302 |
+
{{- raise_exception("Invalid tool call type: " + tool_call.type) -}}
|
| 303 |
+
{%- endif -%}
|
| 304 |
+
{%- endfor -%}
|
| 305 |
+
{{ ']' + end_tool_calls_token }}
|
| 306 |
+
{%- endif -%}
|
| 307 |
+
{%- elif message.role == 'tool' -%}
|
| 308 |
+
{%- if not ns.in_assistant -%}
|
| 309 |
+
{{- raise_exception("Tool message outside of assistant") -}}
|
| 310 |
+
{%- endif -%}
|
| 311 |
+
{%- if not ns.in_tool -%}
|
| 312 |
+
{{ '[' }}
|
| 313 |
+
{%- set ns.in_tool = true -%}
|
| 314 |
+
{%- else -%}
|
| 315 |
+
{{ ", "}}
|
| 316 |
+
{%- endif -%}
|
| 317 |
+
{{ message.content }}
|
| 318 |
+
{%- else -%}
|
| 319 |
+
{{- raise_exception("Invalid message role") -}}
|
| 320 |
+
{%- endif -%}
|
| 321 |
+
{%- endfor -%}
|
| 322 |
+
{%- if ns.in_tool -%}
|
| 323 |
+
{{ ']' }}
|
| 324 |
+
{%- endif -%}
|
| 325 |
+
{%- if add_generation_prompt -%}
|
| 326 |
+
{{ assistant_token }}
|
| 327 |
+
{%- endif -%}
|
llama.cpp/models/templates/ByteDance-Seed-OSS.jinja
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{# ----------‑‑‑ special token variables ‑‑‑---------- #}
|
| 2 |
+
{%- set bos_token = '<seed:bos>' -%}
|
| 3 |
+
{%- set eos_token = '<seed:eos>' -%}
|
| 4 |
+
{%- set pad_token = '<seed:pad>' -%}
|
| 5 |
+
{%- set toolcall_begin_token = '<seed:tool_call>' -%}
|
| 6 |
+
{%- set toolcall_end_token = '</seed:tool_call>' -%}
|
| 7 |
+
{%- set think_begin_token = '<seed:think>' -%}
|
| 8 |
+
{%- set think_end_token = '</seed:think>' -%}
|
| 9 |
+
{%- set budget_begin_token = '<seed:cot_budget_reflect>'-%}
|
| 10 |
+
{%- set budget_end_token = '</seed:cot_budget_reflect>'-%}
|
| 11 |
+
{# -------------- reflection-interval lookup -------------- #}
|
| 12 |
+
{%- if not thinking_budget is defined %}
|
| 13 |
+
{%- set thinking_budget = -1 -%}
|
| 14 |
+
{%- endif -%}
|
| 15 |
+
{%- set budget_reflections_v05 = {
|
| 16 |
+
0: 0,
|
| 17 |
+
512: 128,
|
| 18 |
+
1024: 256,
|
| 19 |
+
2048: 512,
|
| 20 |
+
4096: 512,
|
| 21 |
+
8192: 1024,
|
| 22 |
+
16384: 1024
|
| 23 |
+
} -%}
|
| 24 |
+
{# Find the first gear that is greater than or equal to the thinking_budget. #}
|
| 25 |
+
{%- set ns = namespace(interval = None) -%}
|
| 26 |
+
{%- for k, v in budget_reflections_v05 | dictsort -%}
|
| 27 |
+
{%- if ns.interval is none and thinking_budget <= k -%}
|
| 28 |
+
{%- set ns.interval = v -%}
|
| 29 |
+
{%- endif -%}
|
| 30 |
+
{%- endfor -%}
|
| 31 |
+
{# If it exceeds the maximum gear, use the value of the last gear #}
|
| 32 |
+
{%- if ns.interval is none -%}
|
| 33 |
+
{%- set ns.interval = budget_reflections_v05[16384] -%}
|
| 34 |
+
{%- endif -%}
|
| 35 |
+
{# ---------- Preprocess the system message ---------- #}
|
| 36 |
+
{%- if messages[0]["role"] == "system" %}
|
| 37 |
+
{%- set system_message = messages[0]["content"] %}
|
| 38 |
+
{%- set loop_messages = messages[1:] %}
|
| 39 |
+
{%- else %}
|
| 40 |
+
{%- set loop_messages = messages %}
|
| 41 |
+
{%- endif %}
|
| 42 |
+
{# ---------- Ensure tools exist ---------- #}
|
| 43 |
+
{%- if not tools is defined or tools is none %}
|
| 44 |
+
{%- set tools = [] %}
|
| 45 |
+
{%- endif %}
|
| 46 |
+
{# tools2doc.jinja #}
|
| 47 |
+
{%- macro py_type(t) -%}
|
| 48 |
+
{%- if t == "string" -%}str
|
| 49 |
+
{%- elif t in ("number", "integer") -%}int
|
| 50 |
+
{%- elif t == "boolean" -%}bool
|
| 51 |
+
{%- elif t == "array" -%}list
|
| 52 |
+
{%- else -%}Any{%- endif -%}
|
| 53 |
+
{%- endmacro -%}
|
| 54 |
+
{# ---------- Output the system block ---------- #}
|
| 55 |
+
{%- if system_message is defined %}
|
| 56 |
+
{{ bos_token + "system\n" + system_message }}
|
| 57 |
+
{%- else %}
|
| 58 |
+
{%- if tools is iterable and tools | length > 0 %}
|
| 59 |
+
{{ bos_token + "system\nYou are Doubao, a helpful AI assistant. You may call one or more functions to assist with the user query." }}
|
| 60 |
+
{%- endif %}
|
| 61 |
+
{%- endif %}
|
| 62 |
+
{%- if use_json_tooldef is defined and use_json_tooldef %}
|
| 63 |
+
|
| 64 |
+
{{"Tool List:\nYou are authorized to use the following tools (described in JSON Schema format). Before performing any task, you must decide how to call them based on the descriptions and parameters of these tools."}}
|
| 65 |
+
{{ tools | tojson(ensure_ascii=False) }}
|
| 66 |
+
{%- else %}
|
| 67 |
+
{%- for item in tools if item.type == "function" %}
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
Function:
|
| 71 |
+
def {{ item.function.name }}(
|
| 72 |
+
{%- for name, spec in item.function.parameters.properties.items() %}
|
| 73 |
+
{{- name }}: {{ py_type(spec.type) }}{% if not loop.last %},{% endif %}
|
| 74 |
+
{%- endfor %}):
|
| 75 |
+
"""
|
| 76 |
+
{{ item.function.description | trim }}
|
| 77 |
+
|
| 78 |
+
{# ---------- Args ---------- #}
|
| 79 |
+
{%- if item.function.parameters.properties %}
|
| 80 |
+
Args:
|
| 81 |
+
{%- for name, spec in item.function.parameters.properties.items() %}
|
| 82 |
+
|
| 83 |
+
- {{ name }} ({{ py_type(spec.type) }})
|
| 84 |
+
{%- if name in item.function.parameters.required %} [必填]{% else %} [选填]{% endif %}:
|
| 85 |
+
{{- " " ~ (spec.description or "") }}
|
| 86 |
+
{%- endfor %}
|
| 87 |
+
{%- endif %}
|
| 88 |
+
|
| 89 |
+
{# ---------- Returns ---------- #}
|
| 90 |
+
{%- if item.function.returns is defined
|
| 91 |
+
and item.function.returns.properties is defined
|
| 92 |
+
and item.function.returns.properties %}
|
| 93 |
+
Returns:
|
| 94 |
+
{%- for name, spec in item.function.returns.properties.items() %}
|
| 95 |
+
|
| 96 |
+
- {{ name }} ({{ py_type(spec.type) }}):
|
| 97 |
+
{{- " " ~ (spec.description or "") }}
|
| 98 |
+
{%- endfor %}
|
| 99 |
+
{%- endif %}
|
| 100 |
+
|
| 101 |
+
"""
|
| 102 |
+
{%- endfor %}
|
| 103 |
+
{%- endif %}
|
| 104 |
+
{%- if tools is iterable and tools | length > 0 %}
|
| 105 |
+
|
| 106 |
+
{{"工具调用请遵循如下格式:\n<seed:tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>value_1</parameter>\n<parameter=example_parameter_2>This is the value for the second parameter\nthat can span\nmultiple lines</parameter>\n</function>\n</seed:tool_call>\n"}}
|
| 107 |
+
{%- endif %}
|
| 108 |
+
{# End the system block line #}
|
| 109 |
+
{%- if system_message is defined or tools is iterable and tools | length > 0 %}
|
| 110 |
+
{{ eos_token }}
|
| 111 |
+
{%- endif %}
|
| 112 |
+
{# ---------- Thinking Budget ---------- #}
|
| 113 |
+
{%- if thinking_budget is defined %}
|
| 114 |
+
{%- if thinking_budget == 0 %}
|
| 115 |
+
{{ bos_token+"system" }}
|
| 116 |
+
{{ "You are an intelligent assistant that can answer questions in one step without the need for reasoning and thinking, that is, your thinking budget is 0. Next, please skip the thinking process and directly start answering the user's questions." }}
|
| 117 |
+
{{ eos_token }}
|
| 118 |
+
{%- elif not thinking_budget == -1 %}
|
| 119 |
+
{{ bos_token+"system" }}
|
| 120 |
+
{{ "You are an intelligent assistant with reflective ability. In the process of thinking and reasoning, you need to strictly follow the thinking budget, which is "}}{{thinking_budget}}{{". That is, you need to complete your thinking within "}}{{thinking_budget}}{{" tokens and start answering the user's questions. You will reflect on your thinking process every "}}{{ns.interval}}{{" tokens, stating how many tokens have been used and how many are left."}}
|
| 121 |
+
{{ eos_token }}
|
| 122 |
+
{%- endif %}
|
| 123 |
+
{%- endif %}
|
| 124 |
+
{# ---------- List the historical messages one by one ---------- #}
|
| 125 |
+
{%- for message in loop_messages %}
|
| 126 |
+
{%- if message.role == "assistant"
|
| 127 |
+
and message.tool_calls is defined
|
| 128 |
+
and message.tool_calls is iterable
|
| 129 |
+
and message.tool_calls | length > 0 %}
|
| 130 |
+
{{ bos_token + message.role }}
|
| 131 |
+
{%- if message.reasoning_content is defined and message.reasoning_content is string and message.reasoning_content | trim | length > 0 %}
|
| 132 |
+
{{ "\n" + think_begin_token + message.reasoning_content | trim + think_end_token }}
|
| 133 |
+
{%- endif %}
|
| 134 |
+
{%- if message.content is defined and message.content is string and message.content | trim | length > 0 %}
|
| 135 |
+
{{ "\n" + message.content | trim + "\n" }}
|
| 136 |
+
{%- endif %}
|
| 137 |
+
{%- for tool_call in message.tool_calls %}
|
| 138 |
+
{%- if tool_call.function is defined %}{% set tool_call = tool_call.function %}{% endif %}
|
| 139 |
+
{{ "\n" + toolcall_begin_token + "\n<function=" + tool_call.name + ">\n" }}
|
| 140 |
+
{%- if tool_call.arguments is defined %}
|
| 141 |
+
{%- for arg_name, arg_value in tool_call.arguments | items %}
|
| 142 |
+
{{ "<parameter=" + arg_name + ">" }}
|
| 143 |
+
{%- set arg_value = arg_value if arg_value is string else arg_value | string %}
|
| 144 |
+
{{ arg_value+"</parameter>\n" }}
|
| 145 |
+
{%- endfor %}
|
| 146 |
+
{%- endif %}
|
| 147 |
+
{{ "</function>\n" + toolcall_end_token }}
|
| 148 |
+
{%- endfor %}
|
| 149 |
+
{{ eos_token }}
|
| 150 |
+
{%- elif message.role in ["user", "system"] %}
|
| 151 |
+
{{ bos_token + message.role + "\n" + message.content + eos_token }}
|
| 152 |
+
{%- elif message.role == "assistant" %}
|
| 153 |
+
{{ bos_token + message.role }}
|
| 154 |
+
{%- if message.reasoning_content is defined and message.reasoning_content is string and message.reasoning_content | trim | length > 0 %}
|
| 155 |
+
{{ "\n" + think_begin_token + message.reasoning_content | trim + think_end_token }}
|
| 156 |
+
{%- endif %}
|
| 157 |
+
{%- if message.content is defined and message.content is string and message.content | trim | length > 0 %}
|
| 158 |
+
{{ "\n" + message.content | trim + eos_token }}
|
| 159 |
+
{%- endif %}
|
| 160 |
+
{# Include the tool role #}
|
| 161 |
+
{%- else %}
|
| 162 |
+
{{ bos_token + message.role + "\n" + message.content + eos_token }}
|
| 163 |
+
{%- endif %}
|
| 164 |
+
{%- endfor %}
|
| 165 |
+
{# ---------- Control the model to start continuation ---------- #}
|
| 166 |
+
{%- if add_generation_prompt %}
|
| 167 |
+
{{ bos_token+"assistant\n" }}
|
| 168 |
+
{%- if thinking_budget == 0 %}
|
| 169 |
+
{{ think_begin_token + "\n" + budget_begin_token + "The current thinking budget is 0, so I will directly start answering the question." + budget_end_token + "\n" + think_end_token }}
|
| 170 |
+
{%- endif %}
|
| 171 |
+
{%- endif %}
|
llama.cpp/models/templates/CohereForAI-c4ai-command-r-plus-tool_use.jinja
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
{%- macro json_to_python_type(json_spec) %}
|
| 3 |
+
{%- set basic_type_map = {
|
| 4 |
+
"string": "str",
|
| 5 |
+
"number": "float",
|
| 6 |
+
"integer": "int",
|
| 7 |
+
"boolean": "bool"
|
| 8 |
+
} %}
|
| 9 |
+
|
| 10 |
+
{%- if basic_type_map[json_spec.type] is defined %}
|
| 11 |
+
{{- basic_type_map[json_spec.type] }}
|
| 12 |
+
{%- elif json_spec.type == "array" %}
|
| 13 |
+
{{- "List[" + json_to_python_type(json_spec.items) + "]"}}
|
| 14 |
+
{%- elif json_spec.type == "object" %}
|
| 15 |
+
{{- "Dict[str, " + json_to_python_type(json_spec.additionalProperties) + ']'}}
|
| 16 |
+
{%- elif json_spec.type is iterable %}
|
| 17 |
+
{{- "Union[" }}
|
| 18 |
+
{%- for t in json_spec.type %}
|
| 19 |
+
{{- json_to_python_type({"type": t}) }}
|
| 20 |
+
{%- if not loop.last %}
|
| 21 |
+
{{- "," }}
|
| 22 |
+
{%- endif %}
|
| 23 |
+
{%- endfor %}
|
| 24 |
+
{{- "]" }}
|
| 25 |
+
{%- else %}
|
| 26 |
+
{{- "Any" }}
|
| 27 |
+
{%- endif %}
|
| 28 |
+
{%- endmacro %}
|
| 29 |
+
|
| 30 |
+
{%- macro old_tool_parser(tools) %}
|
| 31 |
+
{%- for tool in tools %}
|
| 32 |
+
{%- if loop.index0 != 0 %}
|
| 33 |
+
{{- '\n\n' }}
|
| 34 |
+
{%- endif %}
|
| 35 |
+
{{- '```python\ndef ' + tool.name + '(' }}
|
| 36 |
+
{%- for param_name, param_fields in tool.parameter_definitions|items %}
|
| 37 |
+
{%- if loop.index0 != 0 %}
|
| 38 |
+
{{- ', '}}
|
| 39 |
+
{%- endif %}
|
| 40 |
+
{{- param_name + ': ' }}
|
| 41 |
+
{%- if not param_fields.required %}
|
| 42 |
+
{{- 'Optional[' + param_fields.type + '] = None'}}
|
| 43 |
+
{%- else %}
|
| 44 |
+
{{- param_fields.type }}
|
| 45 |
+
{%- endif %}
|
| 46 |
+
{%- endfor %}
|
| 47 |
+
{{- ') -> List[Dict]:\n """'}}
|
| 48 |
+
{{- tool.description }}
|
| 49 |
+
{%- if tool.parameter_definitions|length != 0 %}
|
| 50 |
+
{{- '\n\n Args:\n '}}
|
| 51 |
+
{%- for param_name, param_fields in tool.parameter_definitions|items %}
|
| 52 |
+
{%- if loop.index0 != 0 %}
|
| 53 |
+
{{- '\n ' }}
|
| 54 |
+
{%- endif %}
|
| 55 |
+
{{- param_name + ' ('}}
|
| 56 |
+
{%- if not param_fields.required %}
|
| 57 |
+
{{- 'Optional[' + param_fields.type + ']'}}
|
| 58 |
+
{%- else %}
|
| 59 |
+
{{- param_fields.type }}
|
| 60 |
+
{%- endif %}
|
| 61 |
+
{{- '): ' + param_fields.description }}
|
| 62 |
+
{%- endfor %}
|
| 63 |
+
{%- endif %}
|
| 64 |
+
{{- '\n """\n pass\n```' }}
|
| 65 |
+
{%- endfor %}
|
| 66 |
+
{%- endmacro %}
|
| 67 |
+
|
| 68 |
+
{%- macro new_tool_parser(tools) %}
|
| 69 |
+
{%- for tool in tools %}
|
| 70 |
+
{%- if loop.index0 != 0 %}
|
| 71 |
+
{{- '\n\n'}}
|
| 72 |
+
{%- endif %}
|
| 73 |
+
{%- if tool.function is defined %}
|
| 74 |
+
{%- set tool = tool.function %}
|
| 75 |
+
{%- endif %}
|
| 76 |
+
{{-'```python
|
| 77 |
+
def ' + tool.name + '('}}
|
| 78 |
+
{%- for param_name, param_fields in tool.parameters.properties|items %}
|
| 79 |
+
{%- if loop.index0 != 0 %}
|
| 80 |
+
{{- ', '}}
|
| 81 |
+
{%- endif %}
|
| 82 |
+
{{-param_name + ": "}}
|
| 83 |
+
{%- if not param_name in tool.parameters.required %}
|
| 84 |
+
{{-'Optional[' + json_to_python_type(param_fields) + '] = None'}}
|
| 85 |
+
{%- else %}
|
| 86 |
+
{{- json_to_python_type(param_fields) }}
|
| 87 |
+
{%- endif %}
|
| 88 |
+
{%- endfor %}
|
| 89 |
+
{{- ') -> List[Dict]:
|
| 90 |
+
"""'}}
|
| 91 |
+
{{- tool.description }}
|
| 92 |
+
{%- if tool.parameters.properties|length != 0 %}
|
| 93 |
+
{{- '\n\n Args:\n '}}
|
| 94 |
+
{%- for param_name, param_fields in tool.parameters.properties|items %}
|
| 95 |
+
{%- if loop.index0 != 0 %}
|
| 96 |
+
{{- '\n ' }}
|
| 97 |
+
{%- endif %}
|
| 98 |
+
{{- param_name + ' ('}}
|
| 99 |
+
{%- if not param_name in tool.parameters.required %}
|
| 100 |
+
{{-'Optional[' + json_to_python_type(param_fields) + ']'}}
|
| 101 |
+
{%- else %}
|
| 102 |
+
{{- json_to_python_type(param_fields) }}
|
| 103 |
+
{%- endif %}
|
| 104 |
+
{{- '): ' + param_fields.description }}
|
| 105 |
+
{%- endfor %}
|
| 106 |
+
{%- endif %}
|
| 107 |
+
{{- '\n """\n pass\n```' }}
|
| 108 |
+
{%- endfor %}
|
| 109 |
+
{%- endmacro %}
|
| 110 |
+
|
| 111 |
+
{{- bos_token }}
|
| 112 |
+
{%- if messages[0]['role'] == 'system' %}
|
| 113 |
+
{%- set loop_messages = messages[1:] %}
|
| 114 |
+
{%- set system_message = messages[0]['content'] %}
|
| 115 |
+
{%- else %}
|
| 116 |
+
{%- set loop_messages = messages %}
|
| 117 |
+
{%- set system_message = '## Task and Context\nYou help people answer their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You should focus on serving the user\'s needs as best you can, which will be wide-ranging.\n\n## Style Guide\nUnless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling.' %}
|
| 118 |
+
{%- endif %}
|
| 119 |
+
{{- '<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>' }}
|
| 120 |
+
{{- '# Safety Preamble' }}
|
| 121 |
+
{{- '
|
| 122 |
+
The instructions in this section override those in the task description and style guide sections. Don\'t answer questions that are harmful or immoral.' }}
|
| 123 |
+
{{- '
|
| 124 |
+
|
| 125 |
+
# System Preamble' }}
|
| 126 |
+
{{- '
|
| 127 |
+
## Basic Rules' }}
|
| 128 |
+
{{- '
|
| 129 |
+
You are a powerful conversational AI trained by Cohere to help people. You are augmented by a number of tools, and your job is to use and consume the output of these tools to best help the user. You will see a conversation history between yourself and a user, ending with an utterance from the user. You will then see a specific instruction instructing you what kind of response to generate. When you answer the user\'s requests, you cite your sources in your answers, according to those instructions.' }}
|
| 130 |
+
{{- '
|
| 131 |
+
|
| 132 |
+
# User Preamble' }}
|
| 133 |
+
{{- '
|
| 134 |
+
' + system_message }}
|
| 135 |
+
{{-'
|
| 136 |
+
|
| 137 |
+
## Available Tools
|
| 138 |
+
Here is a list of tools that you have available to you:
|
| 139 |
+
|
| 140 |
+
'}}
|
| 141 |
+
{%- set ns = namespace(new_tools=true) %}
|
| 142 |
+
{%- for tool in tools %}
|
| 143 |
+
{%- if tool.parameter_definitions is defined %}
|
| 144 |
+
{%- set ns.new_tools = false %}
|
| 145 |
+
{%- endif %}
|
| 146 |
+
{%- endfor %}
|
| 147 |
+
{%- if ns.new_tools %}
|
| 148 |
+
{{- new_tool_parser(tools) }}
|
| 149 |
+
{%- else %}
|
| 150 |
+
{{- old_tool_parser(tools) }}
|
| 151 |
+
{%- endif %}
|
| 152 |
+
{{- '<|END_OF_TURN_TOKEN|>'}}
|
| 153 |
+
{%- for message in loop_messages %}
|
| 154 |
+
{%- set content = message['content'] %}
|
| 155 |
+
{%- if message.role == 'user' %}
|
| 156 |
+
{{- '<|START_OF_TURN_TOKEN|><|USER_TOKEN|>' + content|trim + '<|END_OF_TURN_TOKEN|>' }}
|
| 157 |
+
{%- elif message.role == 'system' %}
|
| 158 |
+
{{- '<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>' + content|trim + '<|END_OF_TURN_TOKEN|>' }}
|
| 159 |
+
{%- elif message.role == 'assistant' and message.tool_calls is defined %}
|
| 160 |
+
{{- '<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>' }}
|
| 161 |
+
{%- if message.content is defined %}
|
| 162 |
+
{{- message.content|trim }}
|
| 163 |
+
{%- endif %}
|
| 164 |
+
{{- '\nAction:\n```json\n[\n' }}
|
| 165 |
+
{%- for tool_call in message.tool_calls %}
|
| 166 |
+
{%- if tool_call.function is defined %}
|
| 167 |
+
{%- set tool_call = tool_call.function %}
|
| 168 |
+
{%- endif %}
|
| 169 |
+
{{- '{\n'|indent(4, first=true) }}
|
| 170 |
+
{{- '"tool_name": "'|indent(8, first=true) + tool_call.name + '",\n' }}
|
| 171 |
+
{{- '"parameters": '|indent(8, first=true) }}
|
| 172 |
+
{%- if tool_call.arguments is defined and tool_call.arguments|length > 0 %}
|
| 173 |
+
{{- tool_call.arguments|tojson(indent=4)|indent(8) }}
|
| 174 |
+
{{- '\n' }}
|
| 175 |
+
{%- else %}
|
| 176 |
+
{{- '{}\n' }}
|
| 177 |
+
{%- endif %}
|
| 178 |
+
{{- '}'|indent(4, first=true) }}
|
| 179 |
+
{%- if not loop.last %}
|
| 180 |
+
{{- ',\n' }}
|
| 181 |
+
{%- endif %}
|
| 182 |
+
{%- endfor %}
|
| 183 |
+
{{- "\n]```\n" }}
|
| 184 |
+
{%- elif message.role == 'assistant' %}
|
| 185 |
+
{{- '<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>' + content|trim + '<|END_OF_TURN_TOKEN|>' }}
|
| 186 |
+
{%- elif message.role == 'tool' %}
|
| 187 |
+
{{- '<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|><results>\n' }}
|
| 188 |
+
{{- message.content|trim }}
|
| 189 |
+
{{- '</results><|END_OF_TURN_TOKEN|>' }}
|
| 190 |
+
{%- endif %}
|
| 191 |
+
{%- endfor %}
|
| 192 |
+
{{-'<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>Write \'Action:\' followed by a json-formatted list of actions that you want to perform in order to produce a good response to the user\'s last input. You can use any of the supplied tools any number of times, but you should aim to execute the minimum number of necessary actions for the input. You should use the `directly-answer` tool if calling the other tools is unnecessary. The list of actions you want to call should be formatted as a list of json objects, for example:
|
| 193 |
+
```json
|
| 194 |
+
[
|
| 195 |
+
{
|
| 196 |
+
"tool_name": title of the tool in the specification,
|
| 197 |
+
"parameters": a dict of parameters to input into the tool as they are defined in the specs, or {} if it takes no parameters
|
| 198 |
+
}
|
| 199 |
+
]```<|END_OF_TURN_TOKEN|>'}}
|
| 200 |
+
{%- if add_generation_prompt %}
|
| 201 |
+
{{- '<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>' }}
|
| 202 |
+
{%- endif %}
|
llama.cpp/models/templates/CohereForAI-c4ai-command-r7b-12-2024-tool_use.jinja
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{ bos_token }}{%- macro document_turn(documents) -%}
|
| 2 |
+
{# format documents into chat turn #}
|
| 3 |
+
<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|><|START_THINKING|>I will look through the document to address the users needs.<|END_THINKING|><|START_ACTION|>[
|
| 4 |
+
{"tool_call_id": "0", "tool_name": "direct-injected-document", "parameters": {}}
|
| 5 |
+
]<|END_ACTION|><|END_OF_TURN_TOKEN|><|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|><|START_TOOL_RESULT|>[
|
| 6 |
+
{
|
| 7 |
+
"tool_call_id": "0",
|
| 8 |
+
"results": {
|
| 9 |
+
{% for doc in documents %}
|
| 10 |
+
"{{ loop.index0 }}": {{doc|tojson}}{% if not loop.last %},
|
| 11 |
+
{% endif %}
|
| 12 |
+
{% endfor %}
|
| 13 |
+
|
| 14 |
+
},
|
| 15 |
+
"is_error": null
|
| 16 |
+
}
|
| 17 |
+
]<|END_TOOL_RESULT|><|END_OF_TURN_TOKEN|>{%- endmacro %}
|
| 18 |
+
{%- macro tool_call_id_to_int(messages, tool_call_id) %}
|
| 19 |
+
{%- set counter = namespace(value=0) %}
|
| 20 |
+
{%- set tool_call_id_seen = namespace(value=false) %}
|
| 21 |
+
{%- for msg in messages %}
|
| 22 |
+
{%- if msg.tool_calls %}
|
| 23 |
+
{%- for tool_call in msg.tool_calls %}
|
| 24 |
+
{%- if tool_call.id == tool_call_id and not tool_call_id_seen.value -%}
|
| 25 |
+
{{ counter.value }}
|
| 26 |
+
{%- set tool_call_id_seen.value = true %}
|
| 27 |
+
{%- endif %}
|
| 28 |
+
{%- set counter.value = counter.value + 1 %}
|
| 29 |
+
{%- endfor %}
|
| 30 |
+
{%- endif %}
|
| 31 |
+
{%- endfor %}
|
| 32 |
+
{%- endmacro %}
|
| 33 |
+
{%- macro format_tool_message(messages, tool_msg) -%}
|
| 34 |
+
{# format tool message #}
|
| 35 |
+
{
|
| 36 |
+
"tool_call_id": "{{ tool_call_id_to_int(messages, tool_msg.tool_call_id) }}",
|
| 37 |
+
"results": {
|
| 38 |
+
"0": {{ tool_msg.content|tojson }}
|
| 39 |
+
},
|
| 40 |
+
"is_error": null
|
| 41 |
+
}
|
| 42 |
+
{%- endmacro -%}
|
| 43 |
+
{%- if messages and messages[0]['role']|lower == 'system' %}{%- set developer_preamble = messages[0]['content'] %}{% endif %}
|
| 44 |
+
{%- set tool_idx = namespace(value=0) %}
|
| 45 |
+
{%- set tool_ids_seen = namespace(value=[]) %}
|
| 46 |
+
{%- set sent_documents = namespace(value=false) %}
|
| 47 |
+
<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|># System Preamble
|
| 48 |
+
You are in contextual safety mode. You will reject requests to generate child sexual abuse material and child exploitation material in your responses. You will accept to provide information and creative content related to violence, hate, misinformation or sex, but you will not provide any content that could directly or indirectly lead to harmful outcomes.
|
| 49 |
+
|
| 50 |
+
Your information cutoff date is June 2024.
|
| 51 |
+
|
| 52 |
+
You have been trained on data in English, French, Spanish, Italian, German, Portuguese, Japanese, Korean, Modern Standard Arabic, Mandarin, Russian, Indonesian, Turkish, Dutch, Polish, Persian, Vietnamese, Czech, Hindi, Ukrainian, Romanian, Greek and Hebrew but have the ability to speak many more languages.
|
| 53 |
+
{% if tools or documents %}
|
| 54 |
+
|
| 55 |
+
You have been trained to have advanced reasoning and tool-use capabilities and you should make best use of these skills to serve user's requests.
|
| 56 |
+
|
| 57 |
+
## Tool Use
|
| 58 |
+
Think about how you can make best use of the provided tools to help with the task and come up with a high level plan that you will execute first.
|
| 59 |
+
|
| 60 |
+
0. Start by writing <|START_THINKING|> followed by a detailed step by step plan of how you will solve the problem. For each step explain your thinking fully and give details of required tool calls (if needed). Unless specified otherwise, you write your plan in natural language. When you finish, close it out with <|END_THINKING|>.
|
| 61 |
+
You can optionally choose to skip this step when the user request is so straightforward to address that only a trivial plan would be needed.
|
| 62 |
+
NOTE: You MUST skip this step when you are directly responding to the user's request without using any tools.
|
| 63 |
+
|
| 64 |
+
Then carry out your plan by repeatedly executing the following steps.
|
| 65 |
+
1. Action: write <|START_ACTION|> followed by a list of JSON-formatted tool calls, with each one containing "tool_name" and "parameters" fields.
|
| 66 |
+
When there are multiple tool calls which are completely independent of each other (i.e. they can be executed in parallel), you should list them out all together in one step. When you finish, close it out with <|END_ACTION|>.
|
| 67 |
+
2. Observation: you will then receive results of those tool calls in JSON format in the very next turn, wrapped around by <|START_TOOL_RESULT|> and <|END_TOOL_RESULT|>. Carefully observe those results and think about what to do next. Note that these results will be provided to you in a separate turn. NEVER hallucinate results.
|
| 68 |
+
Every tool call produces a list of results (when a tool call produces no result or a single result, it'll still get wrapped inside a list). Each result is clearly linked to its originating tool call via its "tool_call_id".
|
| 69 |
+
3. Reflection: start the next turn by writing <|START_THINKING|> followed by what you've figured out so far, any changes you need to make to your plan, and what you will do next. When you finish, close it out with <|END_THINKING|>.
|
| 70 |
+
You can optionally choose to skip this step when everything is going according to plan and no special pieces of information or reasoning chains need to be recorded.
|
| 71 |
+
NOTE: You MUST skip this step when you are done with tool-use actions and are ready to respond to the user.
|
| 72 |
+
|
| 73 |
+
You can repeat the above 3 steps multiple times (could be 0 times too if no suitable tool calls are available or needed), until you decide it's time to finally respond to the user.
|
| 74 |
+
|
| 75 |
+
4. Response: then break out of the loop and write <|START_RESPONSE|> followed by a piece of text which serves as a response to the user's last request. Use all previous tool calls and results to help you when formulating your response. When you finish, close it out with <|END_RESPONSE|>.
|
| 76 |
+
{% if enable_citations %}
|
| 77 |
+
|
| 78 |
+
## Grounding
|
| 79 |
+
Importantly, note that "Reflection" and "Response" above can be grounded.
|
| 80 |
+
Grounding means you associate pieces of texts (called "spans") with those specific tool results that support them (called "sources"). And you use a pair of tags "<co>" and "</co>" to indicate when a span can be grounded onto a list of sources, listing them out in the closing tag. Sources from the same tool call are grouped together and listed as "{tool_call_id}:[{list of result indices}]", before they are joined together by ",". E.g., "<co>span</co: 0:[1,2],1:[0]>" means that "span" is supported by result 1 and 2 from "tool_call_id=0" as well as result 0 from "tool_call_id=1".
|
| 81 |
+
{% endif %}
|
| 82 |
+
|
| 83 |
+
## Available Tools
|
| 84 |
+
Here is the list of tools that you have available to you.
|
| 85 |
+
You can ONLY use the tools listed here. When a tool is not listed below, it is NOT available and you should NEVER attempt to use it.
|
| 86 |
+
Each tool is represented as a JSON object with fields like "name", "description", "parameters" (per JSON Schema), and optionally, "responses" (per JSON Schema).
|
| 87 |
+
|
| 88 |
+
```json
|
| 89 |
+
[
|
| 90 |
+
{% if documents %}
|
| 91 |
+
{"name": "direct-injected-document", "description": "This is a special tool to directly inject user-uploaded documents into the chat as additional context. DO NOT use this tool by yourself!", "parameters": {"type": "object", "properties": {}, "required": []}, "responses": {"200": {"description": "Successfully returned a list of chunked text snippets from the directly uploaded documents.", "content": {"application/json": {"schema": {"type": "array", "items": {"type": "object", "required": ["url", "snippet"], "properties": {"url": {"type": "string", "description": "The url of the uploaded document."}, "snippet": {"type": "string", "description": "The text snippet for the returned document chunk."}}}}}}}}}{%- if tools %},{% endif %}
|
| 92 |
+
|
| 93 |
+
{% endif %}
|
| 94 |
+
{% for tool in tools %}
|
| 95 |
+
{"name": "{{ tool['function']['name'] }}", "description": "{{tool['function']['description']}}", "parameters": {{ tool['function']['parameters']|tojson }}, "responses": null}{%- if not loop.last %},{% endif %}
|
| 96 |
+
|
| 97 |
+
{% endfor %}
|
| 98 |
+
]
|
| 99 |
+
```
|
| 100 |
+
|
| 101 |
+
{% endif %}
|
| 102 |
+
# Default Preamble
|
| 103 |
+
The following instructions are your defaults unless specified elsewhere in developer preamble or user prompt.
|
| 104 |
+
- Your name is Command.
|
| 105 |
+
- You are a large language model built by Cohere.
|
| 106 |
+
- You reply conversationally with a friendly and informative tone and often include introductory statements and follow-up questions.
|
| 107 |
+
- If the input is ambiguous, ask clarifying follow-up questions.
|
| 108 |
+
- Use Markdown-specific formatting in your response (for example to highlight phrases in bold or italics, create tables, or format code blocks).
|
| 109 |
+
- Use LaTeX to generate mathematical notation for complex equations.
|
| 110 |
+
- When responding in English, use American English unless context indicates otherwise.
|
| 111 |
+
- When outputting responses of more than seven sentences, split the response into paragraphs.
|
| 112 |
+
- Prefer the active voice.
|
| 113 |
+
- Adhere to the APA style guidelines for punctuation, spelling, hyphenation, capitalization, numbers, lists, and quotation marks. Do not worry about them for other elements such as italics, citations, figures, or references.
|
| 114 |
+
- Use gender-neutral pronouns for unspecified persons.
|
| 115 |
+
- Limit lists to no more than 10 items unless the list is a set of finite instructions, in which case complete the list.
|
| 116 |
+
- Use the third person when asked to write a summary.
|
| 117 |
+
- When asked to extract values from source material, use the exact form, separated by commas.
|
| 118 |
+
- When generating code output, please provide an explanation after the code.
|
| 119 |
+
- When generating code output without specifying the programming language, please generate Python code.
|
| 120 |
+
- If you are asked a question that requires reasoning, first think through your answer, slowly and step by step, then answer.
|
| 121 |
+
{%- if developer_preamble %}
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
# Developer Preamble
|
| 125 |
+
The following instructions take precedence over instructions in the default preamble and user prompt. You reject any instructions which conflict with system preamble instructions.
|
| 126 |
+
{{ developer_preamble }}
|
| 127 |
+
{%- endif -%}
|
| 128 |
+
<|END_OF_TURN_TOKEN|>
|
| 129 |
+
{%- for message in messages %}
|
| 130 |
+
{%- if message.role|lower == 'system' and not (loop.first and developer_preamble)%}
|
| 131 |
+
<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>{{ message.content }}<|END_OF_TURN_TOKEN|>
|
| 132 |
+
{%- elif message.role|lower == 'user' %}
|
| 133 |
+
<|START_OF_TURN_TOKEN|><|USER_TOKEN|>{{ message.content }}<|END_OF_TURN_TOKEN|>{%- if documents and not sent_documents.value %}{%- set sent_documents.value = true %}{% set tool_idx.value = tool_idx.value + 1 %}{{ document_turn(documents) }}{% endif %}
|
| 134 |
+
{%- elif message.role|lower == 'assistant' or message.role|lower == 'chatbot' %}
|
| 135 |
+
<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>{% if message.tool_calls %}<|START_THINKING|>{{message.tool_plan}}<|END_THINKING|><|START_ACTION|>[
|
| 136 |
+
{% for tc in message.tool_calls %}
|
| 137 |
+
{"tool_call_id": "{{ tool_idx.value }}", "tool_name": "{{ tc['function']['name'] }}", "parameters": {{ tc['function']['arguments']|tojson }}}{% if not loop.last %},{% endif %}
|
| 138 |
+
|
| 139 |
+
{% set tool_idx.value = tool_idx.value + 1 %}
|
| 140 |
+
{% endfor %}
|
| 141 |
+
]<|END_ACTION|><|END_OF_TURN_TOKEN|>{% else %}<|START_RESPONSE|>{{message.content}}<|END_RESPONSE|><|END_OF_TURN_TOKEN|>{% endif %}
|
| 142 |
+
{% elif message.role|lower == 'tool' and message.tool_call_id not in tool_ids_seen.value %}
|
| 143 |
+
<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|><|START_TOOL_RESULT|>[
|
| 144 |
+
{{ format_tool_message(messages, message) }}
|
| 145 |
+
{%- for msg in messages[loop.index0 + 1:] %}
|
| 146 |
+
{%- if msg.role|lower == 'tool' %},
|
| 147 |
+
{{ format_tool_message(messages, msg) }}
|
| 148 |
+
{%- set tool_ids_seen.value = tool_ids_seen.value + [msg.tool_call_id] %}
|
| 149 |
+
{%- else %}
|
| 150 |
+
{%- break %}
|
| 151 |
+
{%- endif %}
|
| 152 |
+
{%- endfor %}
|
| 153 |
+
|
| 154 |
+
]<|END_TOOL_RESULT|><|END_OF_TURN_TOKEN|>
|
| 155 |
+
{%- endif %}
|
| 156 |
+
{%- endfor %}<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>
|
llama.cpp/models/templates/GLM-4.6.jinja
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[gMASK]<sop>
|
| 2 |
+
{%- if tools -%}
|
| 3 |
+
<|system|>
|
| 4 |
+
# Tools
|
| 5 |
+
|
| 6 |
+
You may call one or more functions to assist with the user query.
|
| 7 |
+
|
| 8 |
+
You are provided with function signatures within <tools></tools> XML tags:
|
| 9 |
+
<tools>
|
| 10 |
+
{% for tool in tools %}
|
| 11 |
+
{{ tool | tojson(ensure_ascii=False) }}
|
| 12 |
+
{% endfor %}
|
| 13 |
+
</tools>
|
| 14 |
+
|
| 15 |
+
For each function call, output the function name and arguments within the following XML format:
|
| 16 |
+
<tool_call>{function-name}
|
| 17 |
+
<arg_key>{arg-key-1}</arg_key>
|
| 18 |
+
<arg_value>{arg-value-1}</arg_value>
|
| 19 |
+
<arg_key>{arg-key-2}</arg_key>
|
| 20 |
+
<arg_value>{arg-value-2}</arg_value>
|
| 21 |
+
...
|
| 22 |
+
</tool_call>{%- endif -%}
|
| 23 |
+
{%- macro visible_text(content) -%}
|
| 24 |
+
{%- if content is string -%}
|
| 25 |
+
{{- content }}
|
| 26 |
+
{%- elif content is iterable and content is not mapping -%}
|
| 27 |
+
{%- for item in content -%}
|
| 28 |
+
{%- if item is mapping and item.type == 'text' -%}
|
| 29 |
+
{{- item.text }}
|
| 30 |
+
{%- elif item is string -%}
|
| 31 |
+
{{- item }}
|
| 32 |
+
{%- endif -%}
|
| 33 |
+
{%- endfor -%}
|
| 34 |
+
{%- else -%}
|
| 35 |
+
{{- content }}
|
| 36 |
+
{%- endif -%}
|
| 37 |
+
{%- endmacro -%}
|
| 38 |
+
{%- set ns = namespace(last_user_index=-1) %}
|
| 39 |
+
{%- for m in messages %}
|
| 40 |
+
{%- if m.role == 'user' %}
|
| 41 |
+
{% set ns.last_user_index = loop.index0 -%}
|
| 42 |
+
{%- endif %}
|
| 43 |
+
{%- endfor %}
|
| 44 |
+
{% for m in messages %}
|
| 45 |
+
{%- if m.role == 'user' -%}<|user|>
|
| 46 |
+
{{ visible_text(m.content) }}
|
| 47 |
+
{{- '/nothink' if (enable_thinking is defined and not enable_thinking and not visible_text(m.content).endswith("/nothink")) else '' -}}
|
| 48 |
+
{%- elif m.role == 'assistant' -%}
|
| 49 |
+
<|assistant|>
|
| 50 |
+
{%- set reasoning_content = '' %}
|
| 51 |
+
{%- set content = visible_text(m.content) %}
|
| 52 |
+
{%- if m.reasoning_content is string %}
|
| 53 |
+
{%- set reasoning_content = m.reasoning_content %}
|
| 54 |
+
{%- else %}
|
| 55 |
+
{%- if '</think>' in content %}
|
| 56 |
+
{%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
|
| 57 |
+
{%- set content = content.split('</think>')[-1].lstrip('\n') %}
|
| 58 |
+
{%- endif %}
|
| 59 |
+
{%- endif %}
|
| 60 |
+
{%- if loop.index0 > ns.last_user_index and reasoning_content -%}
|
| 61 |
+
{{ '\n<think>' + reasoning_content.strip() + '</think>'}}
|
| 62 |
+
{%- else -%}
|
| 63 |
+
{{ '\n<think></think>' }}
|
| 64 |
+
{%- endif -%}
|
| 65 |
+
{%- if content.strip() -%}
|
| 66 |
+
{{ '\n' + content.strip() }}
|
| 67 |
+
{%- endif -%}
|
| 68 |
+
{% if m.tool_calls %}
|
| 69 |
+
{% for tc in m.tool_calls %}
|
| 70 |
+
{%- if tc.function %}
|
| 71 |
+
{%- set tc = tc.function %}
|
| 72 |
+
{%- endif %}
|
| 73 |
+
{{ '\n<tool_call>' + tc.name }}
|
| 74 |
+
{% set _args = tc.arguments or {} %}
|
| 75 |
+
{% if _args is not mapping %}
|
| 76 |
+
{{ raise_exception("Invalid tool call arguments passed: " + _args | string) }}
|
| 77 |
+
{% endif %}
|
| 78 |
+
{% for k, v in _args.items() %}
|
| 79 |
+
<arg_key>{{ k }}</arg_key>
|
| 80 |
+
<arg_value>{{ v | tojson(ensure_ascii=False) if v is not string else v }}</arg_value>
|
| 81 |
+
{% endfor %}
|
| 82 |
+
</tool_call>{% endfor %}
|
| 83 |
+
{% endif %}
|
| 84 |
+
{%- elif m.role == 'tool' -%}
|
| 85 |
+
{%- if m.content is string -%}
|
| 86 |
+
{%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
|
| 87 |
+
{{- '<|observation|>' }}
|
| 88 |
+
{%- endif %}
|
| 89 |
+
{{- '\n<tool_response>\n' }}
|
| 90 |
+
{{- m.content }}
|
| 91 |
+
{{- '\n</tool_response>' }}
|
| 92 |
+
{%- else -%}
|
| 93 |
+
<|observation|>{% for tr in m.content %}
|
| 94 |
+
|
| 95 |
+
<tool_response>
|
| 96 |
+
{{ tr.output if tr.output is defined else tr }}
|
| 97 |
+
</tool_response>{% endfor -%}
|
| 98 |
+
{% endif -%}
|
| 99 |
+
{%- elif m.role == 'system' -%}
|
| 100 |
+
<|system|>
|
| 101 |
+
{{ visible_text(m.content) }}
|
| 102 |
+
{%- endif -%}
|
| 103 |
+
{%- endfor -%}
|
| 104 |
+
{%- if add_generation_prompt -%}
|
| 105 |
+
<|assistant|>{{- '\n<think></think>' if (enable_thinking is defined and not enable_thinking) else '' -}}
|
| 106 |
+
{%- endif -%}
|
llama.cpp/models/templates/Kimi-K2-Instruct.jinja
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% macro render_content(msg) -%}
|
| 2 |
+
{%- set c = msg.get('content') -%}
|
| 3 |
+
{%- if c is string -%}
|
| 4 |
+
{{ c }}
|
| 5 |
+
{%- elif c is not none -%}
|
| 6 |
+
{% for content in c -%}
|
| 7 |
+
{% if content['type'] == 'image' or 'image' in content or 'image_url' in content -%}
|
| 8 |
+
<|media_start|>image<|media_content|><|media_pad|><|media_end|>
|
| 9 |
+
{% else -%}
|
| 10 |
+
{{ content['text'] }}
|
| 11 |
+
{%- endif -%}
|
| 12 |
+
{%- endfor -%}
|
| 13 |
+
{%- endif -%}
|
| 14 |
+
{%- endmacro %}
|
| 15 |
+
|
| 16 |
+
{%- set tool_response_queue = namespace(ids=[]) -%}
|
| 17 |
+
{%- set tool_call_counter = namespace(value=0) -%}
|
| 18 |
+
|
| 19 |
+
{%- if tools -%}
|
| 20 |
+
<|im_system|>tool_declare<|im_middle|>{{ tools | tojson }}<|im_end|>
|
| 21 |
+
{%- endif -%}
|
| 22 |
+
{% for message in messages %}
|
| 23 |
+
{%- if loop.first and messages[0]['role'] != 'system' -%}
|
| 24 |
+
<|im_system|>system<|im_middle|>You are Kimi, an AI assistant created by Moonshot AI.<|im_end|>
|
| 25 |
+
{% endif %}
|
| 26 |
+
|
| 27 |
+
{%- set role_name = message.get('name') or message['role'] -%}
|
| 28 |
+
{%- if message['role'] == 'user' -%}
|
| 29 |
+
<|im_user|>{{role_name}}<|im_middle|>
|
| 30 |
+
{%- elif message['role'] == 'assistant' -%}
|
| 31 |
+
<|im_assistant|>{{role_name}}<|im_middle|>
|
| 32 |
+
{%- else -%}
|
| 33 |
+
<|im_system|>{{role_name}}<|im_middle|>
|
| 34 |
+
{%- endif -%}
|
| 35 |
+
|
| 36 |
+
{%- if message['role'] == 'assistant' and message.get('tool_calls') -%}
|
| 37 |
+
{{render_content(message)}}<|tool_calls_section_begin|>
|
| 38 |
+
{%- for tool_call in message['tool_calls'] -%}
|
| 39 |
+
{%- set formatted_id = 'functions.' + tool_call['function']['name'] + ':' + (tool_call_counter.value | string) -%}
|
| 40 |
+
{%- set tool_call_counter.value = tool_call_counter.value + 1 -%}
|
| 41 |
+
{%- set _ = tool_response_queue.ids.append(formatted_id) -%}
|
| 42 |
+
<|tool_call_begin|>{{ formatted_id }}<|tool_call_argument_begin|>{% if tool_call['function']['arguments'] is string %}{{ tool_call['function']['arguments'] }}{% else %}{{ tool_call['function']['arguments'] | tojson }}{% endif %}<|tool_call_end|>
|
| 43 |
+
{%- endfor -%}
|
| 44 |
+
<|tool_calls_section_end|>
|
| 45 |
+
{%- elif message['role'] == 'tool' -%}
|
| 46 |
+
{%- if tool_response_queue.ids -%}
|
| 47 |
+
{%- set tool_call_id = tool_response_queue.ids.pop(0) -%}
|
| 48 |
+
{%- else -%}
|
| 49 |
+
{%- set tool_call_id = 'functions.' + message.get('name', 'unknown') + ':' + (tool_call_counter.value | string) -%}
|
| 50 |
+
{%- endif -%}
|
| 51 |
+
## Return of {{ tool_call_id }}
|
| 52 |
+
{{render_content(message)}}
|
| 53 |
+
{%- elif message['content'] is not none -%}
|
| 54 |
+
{{render_content(message)}}
|
| 55 |
+
{%- endif -%}
|
| 56 |
+
<|im_end|>
|
| 57 |
+
{%- endfor -%}
|
| 58 |
+
{%- if add_generation_prompt -%}
|
| 59 |
+
<|im_assistant|>assistant<|im_middle|>
|
| 60 |
+
{%- endif -%}
|
llama.cpp/models/templates/Kimi-K2-Thinking.jinja
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- macro render_content(msg) -%}
|
| 2 |
+
{%- set c = msg.get('content') -%}
|
| 3 |
+
{%- if c is string -%}
|
| 4 |
+
{{ c }}
|
| 5 |
+
{%- elif c is not none -%}
|
| 6 |
+
{% for content in c -%}
|
| 7 |
+
{% if content['type'] == 'image' or 'image' in content or 'image_url' in content -%}
|
| 8 |
+
<|media_start|>image<|media_content|><|media_pad|><|media_end|>
|
| 9 |
+
{% else -%}
|
| 10 |
+
{{ content['text'] }}
|
| 11 |
+
{%- endif -%}
|
| 12 |
+
{%- endfor -%}
|
| 13 |
+
{%- endif -%}
|
| 14 |
+
{%- endmacro -%}
|
| 15 |
+
|
| 16 |
+
{% macro set_roles(message) -%}
|
| 17 |
+
{%- set role_name = message.get('name') or message['role'] -%}
|
| 18 |
+
{%- if message['role'] == 'user' -%}
|
| 19 |
+
<|im_user|>{{role_name}}<|im_middle|>
|
| 20 |
+
{%- elif message['role'] == 'assistant' -%}
|
| 21 |
+
<|im_assistant|>{{role_name}}<|im_middle|>
|
| 22 |
+
{%- else -%}
|
| 23 |
+
<|im_system|>{{role_name}}<|im_middle|>
|
| 24 |
+
{%- endif -%}
|
| 25 |
+
{%- endmacro -%}
|
| 26 |
+
|
| 27 |
+
{%- set tool_response_queue = namespace(ids=[]) -%}
|
| 28 |
+
{%- set tool_call_counter = namespace(value=0) -%}
|
| 29 |
+
|
| 30 |
+
{%- macro render_toolcalls(message) -%}
|
| 31 |
+
<|tool_calls_section_begin|>
|
| 32 |
+
{%- for tool_call in message['tool_calls'] -%}
|
| 33 |
+
{%- set formatted_id = 'functions.' + tool_call['function']['name'] + ':' + (tool_call_counter.value | string) -%}
|
| 34 |
+
{%- set tool_call_counter.value = tool_call_counter.value + 1 -%}
|
| 35 |
+
{%- set _ = tool_response_queue.ids.append(formatted_id) -%}
|
| 36 |
+
<|tool_call_begin|>{{ formatted_id }}<|tool_call_argument_begin|>{% if tool_call['function']['arguments'] is string %}{{ tool_call['function']['arguments'] }}{% else %}{{ tool_call['function']['arguments'] | tojson }}{% endif %}<|tool_call_end|>
|
| 37 |
+
{%- endfor -%}
|
| 38 |
+
<|tool_calls_section_end|>
|
| 39 |
+
{%- endmacro -%}
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
{# Find last non-tool-call assisitant message #}
|
| 43 |
+
{%- set ns = namespace(last_non_tool_call_assistant_msg=-1) -%}
|
| 44 |
+
{%- for idx in range(messages|length-1, -1, -1) -%}
|
| 45 |
+
{%- if messages[idx]['role'] == 'assistant' and not messages[idx].get('tool_calls') -%}
|
| 46 |
+
{%- set ns.last_non_tool_call_assistant_msg = idx -%}
|
| 47 |
+
{%- endif -%}
|
| 48 |
+
{%- endfor -%}
|
| 49 |
+
|
| 50 |
+
{# split all messages into history & suffix, reasoning_content in suffix should be reserved.#}
|
| 51 |
+
{%- set hist_msgs = messages[:ns.last_non_tool_call_assistant_msg+1] -%}
|
| 52 |
+
{%- set suffix_msgs = messages[ns.last_non_tool_call_assistant_msg+1:] -%}
|
| 53 |
+
|
| 54 |
+
{%- if tools -%}
|
| 55 |
+
<|im_system|>tool_declare<|im_middle|>{{ tools | tojson }}<|im_end|>
|
| 56 |
+
{%- endif -%}
|
| 57 |
+
|
| 58 |
+
{%- if messages|length == 0 or messages[0]['role'] != 'system' -%}
|
| 59 |
+
<|im_system|>system<|im_middle|>You are Kimi, an AI assistant created by Moonshot AI.<|im_end|>
|
| 60 |
+
{%- endif -%}
|
| 61 |
+
|
| 62 |
+
{%- for message in hist_msgs -%}
|
| 63 |
+
{{set_roles(message)}}
|
| 64 |
+
{%- if message['role'] == 'assistant' -%}
|
| 65 |
+
<think></think>{{render_content(message)}}
|
| 66 |
+
{%- if message.get('tool_calls') -%}
|
| 67 |
+
{{render_toolcalls(message)}}
|
| 68 |
+
{%- endif -%}
|
| 69 |
+
{%- elif message['role'] == 'tool' -%}
|
| 70 |
+
{%- if tool_response_queue.ids -%}
|
| 71 |
+
{%- set tool_call_id = tool_response_queue.ids.pop(0) -%}
|
| 72 |
+
{%- else -%}
|
| 73 |
+
{%- set tool_call_id = 'functions.' + message.get('name', 'unknown') + ':' + (tool_call_counter.value | string) -%}
|
| 74 |
+
{%- endif -%}
|
| 75 |
+
## Return of {{ tool_call_id }}
|
| 76 |
+
{{render_content(message)}}
|
| 77 |
+
{%- elif message['content'] is not none -%}
|
| 78 |
+
{{render_content(message)}}
|
| 79 |
+
{%- endif -%}
|
| 80 |
+
<|im_end|>
|
| 81 |
+
{%- endfor -%}
|
| 82 |
+
|
| 83 |
+
{%- for message in suffix_msgs -%}
|
| 84 |
+
{{set_roles(message)}}
|
| 85 |
+
{%- if message['role'] == 'assistant' -%}
|
| 86 |
+
{%- set rc = message.get('reasoning_content', '') -%}
|
| 87 |
+
<think>{{rc}}</think>{{render_content(message)}}
|
| 88 |
+
{%- if message.get('tool_calls') -%}
|
| 89 |
+
{{render_toolcalls(message)}}
|
| 90 |
+
{%- endif -%}
|
| 91 |
+
{%- elif message['role'] == 'tool' -%}
|
| 92 |
+
{%- if tool_response_queue.ids -%}
|
| 93 |
+
{%- set tool_call_id = tool_response_queue.ids.pop(0) -%}
|
| 94 |
+
{%- else -%}
|
| 95 |
+
{%- set tool_call_id = 'functions.' + message.get('name', 'unknown') + ':' + (tool_call_counter.value | string) -%}
|
| 96 |
+
{%- endif -%}
|
| 97 |
+
## Return of {{ tool_call_id }}
|
| 98 |
+
{{render_content(message)}}
|
| 99 |
+
{%- elif message['content'] is not none -%}
|
| 100 |
+
{{render_content(message)}}
|
| 101 |
+
{%- endif -%}
|
| 102 |
+
<|im_end|>
|
| 103 |
+
{%- endfor -%}
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
{%- if add_generation_prompt -%}
|
| 107 |
+
<|im_assistant|>assistant<|im_middle|>
|
| 108 |
+
{%- endif -%}
|
llama.cpp/models/templates/MiMo-VL.jinja
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- if tools %}
|
| 2 |
+
{{- '<|im_start|>system\n' }}
|
| 3 |
+
{%- if messages[0]['role'] == 'system' %}
|
| 4 |
+
{{- messages[0]['content'] }}
|
| 5 |
+
{%- else %}
|
| 6 |
+
{{- 'You are MiMo, an AI assistant developed by Xiaomi.' }}
|
| 7 |
+
{%- endif %}
|
| 8 |
+
{{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
|
| 9 |
+
{%- for tool in tools %}
|
| 10 |
+
{{- "\n" }}
|
| 11 |
+
{{- tool | tojson }}
|
| 12 |
+
{%- endfor %}
|
| 13 |
+
{{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
|
| 14 |
+
{%- else %}
|
| 15 |
+
{%- if messages[0]['role'] == 'system' %}
|
| 16 |
+
{{- '<|im_start|>system\n' + messages[0]['content'] + '<|im_end|>\n' }}
|
| 17 |
+
{%- else %}
|
| 18 |
+
{{- '<|im_start|>system\nYou are MiMo, an AI assistant developed by Xiaomi.<|im_end|>\n' }}
|
| 19 |
+
{%- endif %}
|
| 20 |
+
{%- endif %}
|
| 21 |
+
{%- for message in messages %}
|
| 22 |
+
{%- if (message.role == "user") or (message.role == "system" and not loop.first) or (message.role == "assistant" and not message.tool_calls) %}
|
| 23 |
+
{{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
|
| 24 |
+
{%- elif message.role == "assistant" %}
|
| 25 |
+
{{- '<|im_start|>' + message.role }}
|
| 26 |
+
{%- if message.content %}
|
| 27 |
+
{{- '\n' + message.content }}
|
| 28 |
+
{%- endif %}
|
| 29 |
+
{%- for tool_call in message.tool_calls %}
|
| 30 |
+
{%- if tool_call.function is defined %}
|
| 31 |
+
{%- set tool_call = tool_call.function %}
|
| 32 |
+
{%- endif %}
|
| 33 |
+
{{- '\n<tool_call>\n{"name": "' }}
|
| 34 |
+
{{- tool_call.name }}
|
| 35 |
+
{{- '", "arguments": ' }}
|
| 36 |
+
{{- tool_call.arguments | tojson }}
|
| 37 |
+
{{- '}\n</tool_call>' }}
|
| 38 |
+
{%- endfor %}
|
| 39 |
+
{{- '<|im_end|>\n' }}
|
| 40 |
+
{%- elif message.role == "tool" %}
|
| 41 |
+
{%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != "tool") %}
|
| 42 |
+
{{- '<|im_start|>user' }}
|
| 43 |
+
{%- endif %}
|
| 44 |
+
{{- '\n<tool_response>\n' }}
|
| 45 |
+
{{- message.content }}
|
| 46 |
+
{{- '\n</tool_response>' }}
|
| 47 |
+
{%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
|
| 48 |
+
{{- '<|im_end|>\n' }}
|
| 49 |
+
{%- endif %}
|
| 50 |
+
{%- endif %}
|
| 51 |
+
{%- endfor %}
|
| 52 |
+
{%- if add_generation_prompt %}
|
| 53 |
+
{{- '<|im_start|>assistant\n' }}
|
| 54 |
+
{%- endif %}
|
llama.cpp/models/templates/MiniMax-M2.jinja
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{# ----------‑‑‑ special token variables ‑‑‑---------- #}
|
| 2 |
+
{%- set toolcall_begin_token = '<minimax:tool_call>' -%}
|
| 3 |
+
{%- set toolcall_end_token = '</minimax:tool_call>' -%}
|
| 4 |
+
{#- Tool Rendering Functions ============================================== -#}
|
| 5 |
+
{%- macro render_tool_namespace(namespace_name, tool_list) -%}
|
| 6 |
+
{%- for tool in tool_list -%}
|
| 7 |
+
<tool>{{ tool.function | tojson(ensure_ascii=False) }}</tool>
|
| 8 |
+
{% endfor -%}
|
| 9 |
+
{%- endmacro -%}
|
| 10 |
+
{%- macro visible_text(content) -%}
|
| 11 |
+
{%- if content is string -%}
|
| 12 |
+
{{ content }}
|
| 13 |
+
{%- elif content is iterable and content is not mapping -%}
|
| 14 |
+
{%- for item in content -%}
|
| 15 |
+
{%- if item is mapping and item.type == 'text' -%}
|
| 16 |
+
{{- item.text }}
|
| 17 |
+
{%- elif item is string -%}
|
| 18 |
+
{{- item }}
|
| 19 |
+
{%- endif -%}
|
| 20 |
+
{%- endfor -%}
|
| 21 |
+
{%- else -%}
|
| 22 |
+
{{- content }}
|
| 23 |
+
{%- endif -%}
|
| 24 |
+
{%- endmacro -%}
|
| 25 |
+
{#- System Message Construction ============================================ -#}
|
| 26 |
+
{%- macro build_system_message(system_message) -%}
|
| 27 |
+
{%- if system_message and system_message.content -%}
|
| 28 |
+
{{- visible_text(system_message.content) }}
|
| 29 |
+
{%- else -%}
|
| 30 |
+
{%- if model_identity is not defined -%}
|
| 31 |
+
{%- set model_identity = "You are a helpful assistant." -%}
|
| 32 |
+
{%- endif -%}
|
| 33 |
+
{{- model_identity }}
|
| 34 |
+
{%- endif -%}
|
| 35 |
+
|
| 36 |
+
{#- Handle current_date -#}
|
| 37 |
+
{%- if system_message and system_message.current_date -%}
|
| 38 |
+
{{- '\n' ~ 'Current date: ' + system_message.current_date }}
|
| 39 |
+
{%- endif -%}
|
| 40 |
+
{#- Handle current_location -#}
|
| 41 |
+
{%- if system_message and system_message.current_location -%}
|
| 42 |
+
{{- '\n' ~ 'Current location: ' + system_message.current_location }}
|
| 43 |
+
{%- endif -%}
|
| 44 |
+
{%- endmacro -%}
|
| 45 |
+
{#- Main Template Logic ================================================= -#}
|
| 46 |
+
{#- Extract system message (only first message if it's system) -#}
|
| 47 |
+
{%- set system_message = none -%}
|
| 48 |
+
{%- set conversation_messages = messages -%}
|
| 49 |
+
{%- if messages and messages[0].role == "system" -%}
|
| 50 |
+
{%- set system_message = messages[0] -%}
|
| 51 |
+
{%- set conversation_messages = messages[1:] -%}
|
| 52 |
+
{%- endif -%}
|
| 53 |
+
{#- Get the last user message turn, for interleved thinking -#}
|
| 54 |
+
{%- set ns = namespace(last_user_index=-1) %}
|
| 55 |
+
{% for m in conversation_messages %}
|
| 56 |
+
{%- if m.role == 'user' %}
|
| 57 |
+
{% set ns.last_user_index = loop.index0 -%}
|
| 58 |
+
{%- endif %}
|
| 59 |
+
{%- endfor %}
|
| 60 |
+
{#- Render system message -#}
|
| 61 |
+
{{- ']~!b[' ~ ']~b]system' ~ '\n' }}
|
| 62 |
+
{{- build_system_message(system_message) }}
|
| 63 |
+
{#- Render tools if available -#}
|
| 64 |
+
{%- if tools -%}
|
| 65 |
+
{{- '\n\n' ~ '# Tools' ~ '\n' ~ 'You may call one or more tools to assist with the user query.\nHere are the tools available in JSONSchema format:' ~ '\n' }}
|
| 66 |
+
{{- '\n' ~ '<tools>' ~ '\n' }}
|
| 67 |
+
{{- render_tool_namespace("functions", tools) }}
|
| 68 |
+
{{- '</tools>' ~ '\n\n' }}
|
| 69 |
+
{{- 'When making tool calls, use XML format to invoke tools and pass parameters:' ~ '\n' }}
|
| 70 |
+
{{- '\n' ~ toolcall_begin_token }}
|
| 71 |
+
<invoke name="tool-name-1">
|
| 72 |
+
<parameter name="param-key-1">param-value-1</parameter>
|
| 73 |
+
<parameter name="param-key-2">param-value-2</parameter>
|
| 74 |
+
...
|
| 75 |
+
</invoke>
|
| 76 |
+
{{- '\n' ~ toolcall_end_token }}
|
| 77 |
+
{%- endif -%}
|
| 78 |
+
{{- '[e~[\n' }}
|
| 79 |
+
|
| 80 |
+
{#- Render messages -#}
|
| 81 |
+
{%- set last_tool_call = namespace(name=none) -%}
|
| 82 |
+
{%- for message in conversation_messages -%}
|
| 83 |
+
{%- if message.role == 'assistant' -%}
|
| 84 |
+
{#- Only render reasoning_content if no user message follows -#}
|
| 85 |
+
{{- ']~b]ai' ~ '\n' }}
|
| 86 |
+
|
| 87 |
+
{%- set reasoning_content = '' %}
|
| 88 |
+
{%- set content = visible_text(message.content) %}
|
| 89 |
+
{%- if message.reasoning_content is string %}
|
| 90 |
+
{%- set reasoning_content = message.reasoning_content %}
|
| 91 |
+
{%- else %}
|
| 92 |
+
{%- if '</think>' in content %}
|
| 93 |
+
{%- set reasoning_content = content.split('</think>')[0].strip('\n').split('<think>')[-1].strip('\n') %}
|
| 94 |
+
{%- set content = content.split('</think>')[-1].strip('\n') %}
|
| 95 |
+
{%- endif %}
|
| 96 |
+
{%- endif %}
|
| 97 |
+
{%- if reasoning_content and loop.index0 > ns.last_user_index -%}
|
| 98 |
+
{{- '<think>' ~ '\n' ~ reasoning_content ~ '\n' ~ '</think>' ~ '\n\n' }}
|
| 99 |
+
{%- endif -%}
|
| 100 |
+
{%- if content -%}
|
| 101 |
+
{{- content }}
|
| 102 |
+
{%- endif -%}
|
| 103 |
+
{%- if message.tool_calls -%}
|
| 104 |
+
{{- '\n' ~ toolcall_begin_token ~ '\n' }}
|
| 105 |
+
|
| 106 |
+
{%- for tool_call in message.tool_calls -%}
|
| 107 |
+
{%- if tool_call.function %}
|
| 108 |
+
{%- set tool_call = tool_call.function %}
|
| 109 |
+
{%- endif %}
|
| 110 |
+
{{- '<invoke name="' + tool_call.name + '">' }}
|
| 111 |
+
{% set _args = tool_call.arguments %}
|
| 112 |
+
{%- for k, v in _args.items() %}
|
| 113 |
+
{{- '<parameter name="' + k + '">' }}
|
| 114 |
+
{{- v | tojson(ensure_ascii=False) if v is not string else v }}
|
| 115 |
+
{{- '</parameter>' }}
|
| 116 |
+
{% endfor %}
|
| 117 |
+
{{- '</invoke>' ~ '\n' }}
|
| 118 |
+
{%- endfor -%}
|
| 119 |
+
|
| 120 |
+
{{- toolcall_end_token}}
|
| 121 |
+
{%- set last_tool_call.name = message.tool_calls[-1].function.name -%}
|
| 122 |
+
{%- else -%}
|
| 123 |
+
{%- set last_tool_call.name = none -%}
|
| 124 |
+
{%- endif -%}
|
| 125 |
+
{{- '[e~[' ~ '\n' }}
|
| 126 |
+
|
| 127 |
+
{%- elif message.role == 'tool' -%}
|
| 128 |
+
{%- if last_tool_call.name is none -%}
|
| 129 |
+
{{- raise_exception("Message has tool role, but there was no previous assistant message with a tool call!") }}
|
| 130 |
+
{%- endif -%}
|
| 131 |
+
{%- if loop.first or (conversation_messages[loop.index0 - 1].role != 'tool') -%}
|
| 132 |
+
{{- ']~b]tool' }}
|
| 133 |
+
{%- endif -%}
|
| 134 |
+
{%- if message.content is string -%}
|
| 135 |
+
{{- '\n<response>' }}
|
| 136 |
+
{{- message.content }}
|
| 137 |
+
{{- '</response>' }}
|
| 138 |
+
{%- else -%}
|
| 139 |
+
{%- for tr in message.content -%}
|
| 140 |
+
{{- '\n<response>' }}
|
| 141 |
+
{{- tr.output if tr.output is defined else (tr.text if tr.type == 'text' and tr.text is defined else tr) }}
|
| 142 |
+
{{- '\n</response>' }}
|
| 143 |
+
{%- endfor -%}
|
| 144 |
+
{%- endif -%}
|
| 145 |
+
{%- if loop.last or (conversation_messages[loop.index0 + 1].role != 'tool') -%}
|
| 146 |
+
{{- '[e~[\n' -}}
|
| 147 |
+
{%- endif -%}
|
| 148 |
+
|
| 149 |
+
{%- elif message.role == 'user' -%}
|
| 150 |
+
{{- ']~b]user' ~ '\n' }}
|
| 151 |
+
{{- visible_text(message.content) }}
|
| 152 |
+
{{- '[e~[' ~ '\n' }}
|
| 153 |
+
{%- endif -%}
|
| 154 |
+
{%- endfor -%}
|
| 155 |
+
|
| 156 |
+
{#- Generation prompt -#}
|
| 157 |
+
{%- if add_generation_prompt -%}
|
| 158 |
+
{{- ']~b]ai' ~ '\n' ~ '<think>' ~ '\n' }}
|
| 159 |
+
{%- endif -%}
|
llama.cpp/models/templates/deepseek-ai-DeepSeek-R1-Distill-Llama-8B.jinja
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, is_output_first=true, system_prompt='') %}{%- for message in messages %}{%- if message['role'] == 'system' %}{% set ns.system_prompt = message['content'] %}{%- endif %}{%- endfor %}{{bos_token}}{{ns.system_prompt}}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{{'<|User|>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is none %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls']%}{%- if not ns.is_first %}{{'<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\n' + '```json' + '\n' + tool['function']['arguments'] + '\n' + '```' + '<|tool▁call▁end|>'}}{%- set ns.is_first = true -%}{%- else %}{{'\n' + '<|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\n' + '```json' + '\n' + tool['function']['arguments'] + '\n' + '```' + '<|tool▁call▁end|>'}}{{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}{%- endif %}{%- endfor %}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is not none %}{%- if ns.is_tool %}{{'<|tool▁outputs▁end|>' + message['content'] + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}{%- else %}{% set content = message['content'] %}{% if '</think>' in content %}{% set content = content.split('</think>')[-1] %}{% endif %}{{'<|Assistant|>' + content + '<|end▁of▁sentence|>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_tool = true -%}{%- if ns.is_output_first %}{{'<|tool▁outputs▁begin|><|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- set ns.is_output_first = false %}{%- else %}{{'\n<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- endif %}{%- endif %}{%- endfor -%}{% if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}{% endif %}{% if add_generation_prompt and not ns.is_tool %}{{'<|Assistant|><think>\n'}}{% endif %}
|
llama.cpp/models/templates/deepseek-ai-DeepSeek-R1-Distill-Qwen-32B.jinja
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, is_output_first=true, system_prompt='') %}{%- for message in messages %}{%- if message['role'] == 'system' %}{% set ns.system_prompt = message['content'] %}{%- endif %}{%- endfor %}{{bos_token}}{{ns.system_prompt}}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{{'<|User|>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is none %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls']%}{%- if not ns.is_first %}{{'<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\n' + '```json' + '\n' + tool['function']['arguments'] + '\n' + '```' + '<|tool▁call▁end|>'}}{%- set ns.is_first = true -%}{%- else %}{{'\n' + '<|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\n' + '```json' + '\n' + tool['function']['arguments'] + '\n' + '```' + '<|tool▁call▁end|>'}}{{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}{%- endif %}{%- endfor %}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is not none %}{%- if ns.is_tool %}{{'<|tool▁outputs▁end|>' + message['content'] + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}{%- else %}{% set content = message['content'] %}{% if '</think>' in content %}{% set content = content.split('</think>')[-1] %}{% endif %}{{'<|Assistant|>' + content + '<|end▁of▁sentence|>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_tool = true -%}{%- if ns.is_output_first %}{{'<|tool▁outputs▁begin|><|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- set ns.is_output_first = false %}{%- else %}{{'\n<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- endif %}{%- endif %}{%- endfor -%}{% if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}{% endif %}{% if add_generation_prompt and not ns.is_tool %}{{'<|Assistant|><think>\n'}}{% endif %}
|
llama.cpp/models/templates/deepseek-ai-DeepSeek-V3.1.jinja
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% if not thinking is defined %}{% set thinking = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, system_prompt='', is_first_sp=true, is_last_user=false) %}{%- for message in messages %}{%- if message['role'] == 'system' %}{%- if ns.is_first_sp %}{% set ns.system_prompt = ns.system_prompt + message['content'] %}{% set ns.is_first_sp = false %}{%- else %}{% set ns.system_prompt = ns.system_prompt + '
|
| 2 |
+
|
| 3 |
+
' + message['content'] %}{%- endif %}{%- endif %}{%- endfor %}{{ bos_token }}{{ ns.system_prompt }}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{%- set ns.is_first = false -%}{%- set ns.is_last_user = true -%}{{'<|User|>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['tool_calls'] is defined and message['tool_calls'] is not none %}{%- if ns.is_last_user %}{{'<|Assistant|></think>'}}{%- endif %}{%- set ns.is_last_user = false -%}{%- set ns.is_first = false %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls'] %}{%- if not ns.is_first %}{%- if message['content'] is none %}{{'<|tool▁calls▁begin|><|tool▁call▁begin|>'+ tool['function']['name'] + '<|tool▁sep|>' + tool['function']['arguments'] + '<|tool▁call▁end|>'}}{%- else %}{{message['content'] + '<|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['function']['name'] + '<|tool▁sep|>' + tool['function']['arguments'] + '<|tool▁call▁end|>'}}{%- endif %}{%- set ns.is_first = true -%}{%- else %}{{'<|tool▁call▁begin|>'+ tool['function']['name'] + '<|tool▁sep|>' + tool['function']['arguments'] + '<|tool▁call▁end|>'}}{%- endif %}{%- endfor %}{{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}{%- endif %}{%- if message['role'] == 'assistant' and (message['tool_calls'] is not defined or message['tool_calls'] is none) %}{%- if ns.is_last_user %}{{'<|Assistant|>'}}{%- if message['prefix'] is defined and message['prefix'] and thinking %}{{'<think>'}} {%- else %}{{'</think>'}}{%- endif %}{%- endif %}{%- set ns.is_last_user = false -%}{%- if ns.is_tool %}{{message['content'] + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}{%- else %}{%- set content = message['content'] -%}{%- if '</think>' in content %}{%- set content = content.split('</think>', 1)[1] -%}{%- endif %}{{content + '<|end▁of▁sentence|>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_last_user = false -%}{%- set ns.is_tool = true -%}{{'<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- endif %}{%- endfor -%}{%- if add_generation_prompt and ns.is_last_user and not ns.is_tool %}{{'<|Assistant|>'}}{%- if not thinking %}{{'</think>'}}{%- else %}{{'<think>'}}{%- endif %}{% endif %}
|
llama.cpp/models/templates/fireworks-ai-llama-3-firefunction-v2.jinja
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- set loop_messages = messages -%}
|
| 2 |
+
{%- set message_roles = ['system', 'user', 'assistant', 'tool'] -%}
|
| 3 |
+
{%- set system_prompt_suffix -%}
|
| 4 |
+
{%- filter trim -%}
|
| 5 |
+
In addition to plain text responses, you can chose to call one or more of the provided functions.
|
| 6 |
+
|
| 7 |
+
Use the following rule to decide when to call a function:
|
| 8 |
+
* if the response can be generated from your internal knowledge (e.g., as in the case of queries like "What is the capital of Poland?"), do so
|
| 9 |
+
* if you need external information that can be obtained by calling one or more of the provided functions, generate a function calls
|
| 10 |
+
|
| 11 |
+
If you decide to call functions:
|
| 12 |
+
* prefix function calls with functools marker (no closing marker required)
|
| 13 |
+
* all function calls should be generated in a single JSON list formatted as functools[{"name": [function name], "arguments": [function arguments as JSON]}, ...]
|
| 14 |
+
* follow the provided JSON schema. Do not hallucinate arguments or values. Do to blindly copy values from the provided samples
|
| 15 |
+
* respect the argument type formatting. E.g., if the type if number and format is float, write value 7 as 7.0
|
| 16 |
+
* make sure you pick the right functions that match the user intent
|
| 17 |
+
|
| 18 |
+
Available functions as JSON spec:
|
| 19 |
+
{%- endfilter -%}
|
| 20 |
+
{%- endset -%}
|
| 21 |
+
{%- set system_prompt_suffix = system_prompt_suffix + "\n" + functions -%}
|
| 22 |
+
{%- set system_prompt_suffix = system_prompt_suffix + '\nToday is ' + datetime + '.' -%}
|
| 23 |
+
{%- set ns = namespace(role='', content='') -%}
|
| 24 |
+
{#- Basic consistency checks -#}
|
| 25 |
+
{%- if not loop_messages -%}
|
| 26 |
+
{{ raise_exception('Expected non-empty messages') }}
|
| 27 |
+
{%- endif -%}
|
| 28 |
+
{%- for message in loop_messages -%}
|
| 29 |
+
{%- set ns.role = message['role'] | lower -%}
|
| 30 |
+
{%- if ns.role not in message_roles -%}
|
| 31 |
+
{%- set message_roles_string = message_roles | join(', ') -%}
|
| 32 |
+
{{ raise_exception('Invalid role ' + message['role'] + '. Only ' + message_roles_string + ' are supported.') }}
|
| 33 |
+
{%- endif -%}
|
| 34 |
+
{%- set msg_content = message['content'] | default('', true) | trim -%}
|
| 35 |
+
{%- if loop.index0 == 0 -%}
|
| 36 |
+
{%- if ns.role == 'system' -%}
|
| 37 |
+
{%- set system_prompt = '<|start_header_id|>' + 'system' + '<|end_header_id|>\n\n' + message['content'] | trim + '\n' + system_prompt_suffix + '<|eot_id|>' -%}
|
| 38 |
+
{%- else -%}
|
| 39 |
+
{%- set system_prompt = '<|start_header_id|>' + 'system' + '<|end_header_id|>\n\nYou are a helpful assistant with access to functions.\n' + system_prompt_suffix + '<|eot_id|>' -%}
|
| 40 |
+
{%- endif -%}
|
| 41 |
+
{%- set ns.content = bos_token + system_prompt -%}
|
| 42 |
+
{{- ns.content -}}
|
| 43 |
+
{%- endif -%}
|
| 44 |
+
{%- if loop.index0 > 0 or ns.role != 'system' -%}
|
| 45 |
+
{%- set ns.content = '<|start_header_id|>' + ns.role + '<|end_header_id|>\n\n' + msg_content -%}
|
| 46 |
+
{%- if 'tool_calls' in message and message['tool_calls'] -%}
|
| 47 |
+
{%- set tool = namespace(calls=[]) -%}
|
| 48 |
+
{%- for call in message['tool_calls'] -%}
|
| 49 |
+
{%- set tool.calls = tool.calls + ['{"name": "' + call['function']['name'] + '", "arguments": ' + call['function']['arguments'] + '}'] -%}
|
| 50 |
+
{%- endfor -%}
|
| 51 |
+
{%- set ns.content = ns.content + ' functools[' + tool.calls | join(', ') + ']' -%}
|
| 52 |
+
{%- endif -%}
|
| 53 |
+
{%- set ns.content = ns.content + '<|eot_id|>' -%}
|
| 54 |
+
{{- ns.content -}}
|
| 55 |
+
{%- endif -%}
|
| 56 |
+
{%- endfor -%}
|
| 57 |
+
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
|
llama.cpp/models/templates/google-gemma-2-2b-it.jinja
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{ bos_token }}{% if messages[0]['role'] == 'system' %}{{ raise_exception('System role not supported') }}{% endif %}{% for message in messages %}{% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %}{{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }}{% endif %}{% if (message['role'] == 'assistant') %}{% set role = 'model' %}{% else %}{% set role = message['role'] %}{% endif %}{{ '<start_of_turn>' + role + '
|
| 2 |
+
' + message['content'] | trim + '<end_of_turn>
|
| 3 |
+
' }}{% endfor %}{% if add_generation_prompt %}{{'<start_of_turn>model
|
| 4 |
+
'}}{% endif %}
|
llama.cpp/models/templates/ibm-granite-granite-3.3-2B-Instruct.jinja
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{# Alias tools -> available_tools #}
|
| 2 |
+
{%- if tools and not available_tools -%}
|
| 3 |
+
{%- set available_tools = tools -%}
|
| 4 |
+
{%- endif -%}
|
| 5 |
+
{%- if messages[0]['role'] == 'system' %}
|
| 6 |
+
{%- set system_message = messages[0]['content'] %}
|
| 7 |
+
{%- set loop_messages = messages[1:] %}
|
| 8 |
+
{%- else %}
|
| 9 |
+
{%- set system_message = "Knowledge Cutoff Date: April 2024. Today's Date: " + strftime_now('%B %d, %Y') + ". You are Granite, developed by IBM." %}
|
| 10 |
+
{%- if available_tools and documents %}
|
| 11 |
+
{%- set system_message = system_message + " You are a helpful assistant with access to the following tools. When a tool is required to answer the user's query, respond only with <|tool_call|> followed by a JSON list of tools used. If a tool does not exist in the provided list of tools, notify the user that you do not have the ability to fulfill the request. Write the response to the user's input by strictly aligning with the facts in the provided documents. If the information needed to answer the question is not available in the documents, inform the user that the question cannot be answered based on the available data." %}
|
| 12 |
+
{%- elif available_tools %}
|
| 13 |
+
{%- set system_message = system_message + " You are a helpful assistant with access to the following tools. When a tool is required to answer the user's query, respond only with <|tool_call|> followed by a JSON list of tools used. If a tool does not exist in the provided list of tools, notify the user that you do not have the ability to fulfill the request." %}
|
| 14 |
+
{%- elif documents %}
|
| 15 |
+
{%- set system_message = system_message + " Write the response to the user's input by strictly aligning with the facts in the provided documents. If the information needed to answer the question is not available in the documents, inform the user that the question cannot be answered based on the available data." %}
|
| 16 |
+
{%- elif thinking %}
|
| 17 |
+
{%- set system_message = system_message + " You are a helpful AI assistant.
|
| 18 |
+
Respond to every user query in a comprehensive and detailed way. You can write down your thoughts and reasoning process before responding. In the thought process, engage in a comprehensive cycle of analysis, summarization, exploration, reassessment, reflection, backtracing, and iteration to develop well-considered thinking process. In the response section, based on various attempts, explorations, and reflections from the thoughts section, systematically present the final solution that you deem correct. The response should summarize the thought process. Write your thoughts between <think></think> and write your response between <response></response> for each user query." %}
|
| 19 |
+
{%- else %}
|
| 20 |
+
{%- set system_message = system_message + " You are a helpful AI assistant." %}
|
| 21 |
+
{%- endif %}
|
| 22 |
+
{%- if 'citations' in controls and documents %}
|
| 23 |
+
{%- set system_message = system_message + '
|
| 24 |
+
Use the symbols <|start_of_cite|> and <|end_of_cite|> to indicate when a fact comes from a document in the search result, e.g <|start_of_cite|> {document_id: 1}my fact <|end_of_cite|> for a fact from document 1. Afterwards, list all the citations with their corresponding documents in an ordered list.' %}
|
| 25 |
+
{%- endif %}
|
| 26 |
+
{%- if 'hallucinations' in controls and documents %}
|
| 27 |
+
{%- set system_message = system_message + '
|
| 28 |
+
Finally, after the response is written, include a numbered list of sentences from the response with a corresponding risk value that are hallucinated and not based in the documents.' %}
|
| 29 |
+
{%- endif %}
|
| 30 |
+
{%- set loop_messages = messages %}
|
| 31 |
+
{%- endif %}
|
| 32 |
+
{{- '<|start_of_role|>system<|end_of_role|>' + system_message + '<|end_of_text|>
|
| 33 |
+
' }}
|
| 34 |
+
{%- if available_tools %}
|
| 35 |
+
{{- '<|start_of_role|>available_tools<|end_of_role|>' }}
|
| 36 |
+
{{- available_tools | tojson(indent=4) }}
|
| 37 |
+
{{- '<|end_of_text|>
|
| 38 |
+
' }}
|
| 39 |
+
{%- endif %}
|
| 40 |
+
{%- if documents %}
|
| 41 |
+
{%- for document in documents %}
|
| 42 |
+
{{- '<|start_of_role|>document {"document_id": "' + document['doc_id'] | string + '"}<|end_of_role|>
|
| 43 |
+
' }}
|
| 44 |
+
{{- document['text'] }}
|
| 45 |
+
{{- '<|end_of_text|>
|
| 46 |
+
' }}
|
| 47 |
+
{%- endfor %}
|
| 48 |
+
{%- endif %}
|
| 49 |
+
{%- for message in loop_messages %}
|
| 50 |
+
{{- '<|start_of_role|>' + message['role'] + '<|end_of_role|>' + message['content'] + '<|end_of_text|>
|
| 51 |
+
' }}
|
| 52 |
+
{%- if loop.last and add_generation_prompt %}
|
| 53 |
+
{{- '<|start_of_role|>assistant' }}
|
| 54 |
+
{%- if controls %}
|
| 55 |
+
{{- ' ' + controls | tojson()}}
|
| 56 |
+
{%- endif %}
|
| 57 |
+
{{- '<|end_of_role|>' }}
|
| 58 |
+
{%- endif %}
|
| 59 |
+
{%- endfor %}
|
llama.cpp/models/templates/llama-cpp-deepseek-r1.jinja
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- if not add_generation_prompt is defined -%}
|
| 2 |
+
{%- set add_generation_prompt = false -%}
|
| 3 |
+
{%- endif -%}
|
| 4 |
+
{%- set ns = namespace(is_first=false, is_tool_outputs=false, is_output_first=true, system_prompt='') -%}
|
| 5 |
+
{%- for message in messages -%}
|
| 6 |
+
{%- if message['role'] == 'system' -%}
|
| 7 |
+
{%- set ns.system_prompt = message['content'] -%}
|
| 8 |
+
{%- endif -%}
|
| 9 |
+
{%- endfor -%}
|
| 10 |
+
{{bos_token}}
|
| 11 |
+
{%- if tools %}
|
| 12 |
+
You can call any of the following function tools to satisfy the user's requests: {{tools | map(attribute='function') | tojson(indent=2)}}
|
| 13 |
+
|
| 14 |
+
Example function tool call syntax:
|
| 15 |
+
|
| 16 |
+
<|tool▁calls▁begin|><|tool▁call▁begin|>function<|tool▁sep|>example_function_name
|
| 17 |
+
```json
|
| 18 |
+
{
|
| 19 |
+
"arg1": "some_value"
|
| 20 |
+
...
|
| 21 |
+
}
|
| 22 |
+
```
|
| 23 |
+
<|tool▁call▁end|><|tool▁calls▁end|>
|
| 24 |
+
|
| 25 |
+
{% endif -%}
|
| 26 |
+
{{ns.system_prompt}}
|
| 27 |
+
{%- macro flush_tool_outputs() -%}
|
| 28 |
+
{%- if ns.is_tool_outputs -%}
|
| 29 |
+
{{- '<|tool▁outputs▁end|><|end▁of▁sentence|>' -}}
|
| 30 |
+
{%- set ns.is_tool_outputs = false -%}
|
| 31 |
+
{%- endif -%}
|
| 32 |
+
{%- endmacro -%}
|
| 33 |
+
{{- flush_tool_outputs() -}}
|
| 34 |
+
{%- for message in messages -%}
|
| 35 |
+
{%- if message['role'] != 'tool' -%}
|
| 36 |
+
{{- flush_tool_outputs() -}}
|
| 37 |
+
{%- endif -%}
|
| 38 |
+
{%- if message['role'] == 'user' -%}
|
| 39 |
+
{{- '<|User|>' + message['content'] + '<|end▁of▁sentence|>' -}}
|
| 40 |
+
{%- endif -%}
|
| 41 |
+
{%- if message['role'] == 'assistant' and not message['content'] -%}
|
| 42 |
+
{{- '<|Assistant|><|tool▁calls▁begin|>' -}}
|
| 43 |
+
{%- set ns.is_first = true -%}
|
| 44 |
+
{%- for tc in message['tool_calls'] -%}
|
| 45 |
+
{%- if ns.is_first -%}
|
| 46 |
+
{%- set ns.is_first = false -%}
|
| 47 |
+
{%- else -%}
|
| 48 |
+
{{- '\n' -}}
|
| 49 |
+
{%- endif -%}
|
| 50 |
+
{%- set tool_name = tc['function']['name'] -%}
|
| 51 |
+
{%- set tool_args = tc['function']['arguments'] -%}
|
| 52 |
+
{{- '<|tool▁call▁begin|>' + tc['type'] + '<|tool▁sep|>' + tool_name + '\n' + '```json' + '\n' + tool_args + '\n' + '```' + '<|tool▁call▁end|>' -}}
|
| 53 |
+
{%- endfor -%}
|
| 54 |
+
{{- '<|tool▁calls▁end|><|end▁of▁sentence|>' -}}
|
| 55 |
+
{%- endif -%}
|
| 56 |
+
{%- if message['role'] == 'assistant' and message['content'] -%}
|
| 57 |
+
{{- flush_tool_outputs() -}}
|
| 58 |
+
{%- set content = message['content'] -%}
|
| 59 |
+
{%- if '</think>' in content -%}
|
| 60 |
+
{%- set content = content.split('</think>')[-1] -%}
|
| 61 |
+
{%- endif -%}
|
| 62 |
+
{{- '<|Assistant|>' + content + '<|end▁of▁sentence|>' -}}
|
| 63 |
+
{%- endif -%}
|
| 64 |
+
{%- if message['role'] == 'tool' -%}
|
| 65 |
+
{%- set ns.is_tool_outputs = true -%}
|
| 66 |
+
{%- if ns.is_output_first -%}
|
| 67 |
+
{{- '<|tool▁outputs▁begin|>' -}}
|
| 68 |
+
{%- set ns.is_output_first = false -%}
|
| 69 |
+
{%- endif -%}
|
| 70 |
+
{{- '\n<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>' -}}
|
| 71 |
+
{%- endif -%}
|
| 72 |
+
{%- endfor -%}
|
| 73 |
+
{{- flush_tool_outputs() -}}
|
| 74 |
+
{%- if add_generation_prompt and not ns.is_tool_outputs -%}
|
| 75 |
+
{{- '<|Assistant|><think>\n' -}}
|
| 76 |
+
{%- endif -%}
|
llama.cpp/models/templates/llama-cpp-lfm2.jinja
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- bos_token -}}
|
| 2 |
+
{%- set system_prompt = "" -%}
|
| 3 |
+
{%- set ns = namespace(system_prompt="") -%}
|
| 4 |
+
{%- if messages[0]["role"] == "system" -%}
|
| 5 |
+
{%- set ns.system_prompt = messages[0]["content"] -%}
|
| 6 |
+
{%- set messages = messages[1:] -%}
|
| 7 |
+
{%- endif -%}
|
| 8 |
+
{%- if tools -%}
|
| 9 |
+
{%- set ns.system_prompt = ns.system_prompt + ("\n" if ns.system_prompt else "") + "List of tools: <|tool_list_start|>[" -%}
|
| 10 |
+
{%- for tool in tools -%}
|
| 11 |
+
{%- if tool is not string -%}
|
| 12 |
+
{%- set tool = tool | tojson -%}
|
| 13 |
+
{%- endif -%}
|
| 14 |
+
{%- set ns.system_prompt = ns.system_prompt + tool -%}
|
| 15 |
+
{%- if not loop.last -%}
|
| 16 |
+
{%- set ns.system_prompt = ns.system_prompt + ", " -%}
|
| 17 |
+
{%- endif -%}
|
| 18 |
+
{%- endfor -%}
|
| 19 |
+
{%- set ns.system_prompt = ns.system_prompt + "]<|tool_list_end|>" -%}
|
| 20 |
+
{%- endif -%}
|
| 21 |
+
{%- if ns.system_prompt -%}
|
| 22 |
+
{{- "<|im_start|>system\n" + ns.system_prompt + "<|im_end|>\n" -}}
|
| 23 |
+
{%- endif -%}
|
| 24 |
+
{%- for message in messages -%}
|
| 25 |
+
{{- "<|im_start|>" + message["role"] + "\n" -}}
|
| 26 |
+
{%- set content = message["content"] -%}
|
| 27 |
+
{%- if content is not string -%}
|
| 28 |
+
{%- set content = content | tojson -%}
|
| 29 |
+
{%- endif -%}
|
| 30 |
+
{%- if message["role"] == "tool" -%}
|
| 31 |
+
{%- set content = "<|tool_response_start|>" + content + "<|tool_response_end|>" -%}
|
| 32 |
+
{%- endif -%}
|
| 33 |
+
{{- content + "<|im_end|>\n" -}}
|
| 34 |
+
{%- endfor -%}
|
| 35 |
+
{%- if add_generation_prompt -%}
|
| 36 |
+
{{- "<|im_start|>assistant\n" -}}
|
| 37 |
+
{%- endif -%}
|
llama.cpp/models/templates/llama-cpp-rwkv-world.jinja
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- if not add_generation_prompt is defined -%}
|
| 2 |
+
{%- set add_generation_prompt = true -%}
|
| 3 |
+
{%- endif -%}
|
| 4 |
+
{%- set ns = namespace(system_prompt='') -%}
|
| 5 |
+
{%- for message in messages -%}
|
| 6 |
+
{%- if message['role'] == 'system' -%}
|
| 7 |
+
{%- set ns.system_prompt = message['content'] -%}
|
| 8 |
+
{%- endif -%}
|
| 9 |
+
{%- endfor -%}
|
| 10 |
+
{{bos_token}}
|
| 11 |
+
{%- if ns.system_prompt != '' -%}
|
| 12 |
+
{{- 'System: ' + ns.system_prompt + '\n\n' -}}
|
| 13 |
+
{%- endif -%}
|
| 14 |
+
{%- for message in messages -%}
|
| 15 |
+
{%- if message['role'] == 'user' -%}
|
| 16 |
+
{{- 'User: ' + message['content']|trim + '\n\n' -}}
|
| 17 |
+
{%- endif -%}
|
| 18 |
+
{%- if message['role'] == 'assistant' and message['content'] is not none -%}
|
| 19 |
+
{%- set content = message['content'] -%}
|
| 20 |
+
{%- if '</think>' in content -%}
|
| 21 |
+
{%- set content = content.split('</think>')[-1] -%}
|
| 22 |
+
{%- endif -%}
|
| 23 |
+
{{- 'Assistant: ' + content|trim + '\n\n' -}}
|
| 24 |
+
{%- endif -%}
|
| 25 |
+
{%- endfor -%}
|
| 26 |
+
{%- if add_generation_prompt -%}
|
| 27 |
+
{{- 'Assistant:' -}}
|
| 28 |
+
{%- if enable_thinking is defined and enable_thinking is false %}
|
| 29 |
+
{{- ' <think>\n</think>' }}
|
| 30 |
+
{%- endif %}
|
| 31 |
+
{%- if enable_thinking is defined and enable_thinking is true %}
|
| 32 |
+
{{- ' <think>' }}
|
| 33 |
+
{%- endif %}
|
| 34 |
+
{%- endif -%}
|
llama.cpp/models/templates/meetkai-functionary-medium-v3.1.jinja
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{# version=v3-llama3.1 #}{%- if not tools is defined -%}
|
| 2 |
+
{%- set tools = none -%}
|
| 3 |
+
{%- endif -%}
|
| 4 |
+
|
| 5 |
+
{%- set has_code_interpreter = tools | selectattr("type", "equalto", "code_interpreter") | list | length > 0 -%}
|
| 6 |
+
{%- if has_code_interpreter -%}
|
| 7 |
+
{%- set tools = tools | rejectattr("type", "equalto", "code_interpreter") | list -%}
|
| 8 |
+
{%- endif -%}
|
| 9 |
+
|
| 10 |
+
{#- System message + builtin tools #}
|
| 11 |
+
{{- bos_token + "<|start_header_id|>system<|end_header_id|>\n\n" }}
|
| 12 |
+
{%- if has_code_interpreter %}
|
| 13 |
+
{{- "Environment: ipython\n\n" }}
|
| 14 |
+
{%- else -%}
|
| 15 |
+
{{ "\n"}}
|
| 16 |
+
{%- endif %}
|
| 17 |
+
{{- "Cutting Knowledge Date: December 2023\n\n" }}
|
| 18 |
+
{%- if tools %}
|
| 19 |
+
{{- "\nYou have access to the following functions:\n\n" }}
|
| 20 |
+
{%- for t in tools %}
|
| 21 |
+
{%- if "type" in t -%}
|
| 22 |
+
{{ "Use the function '"|safe + t["function"]["name"] + "' to '"|safe + t["function"]["description"] + "'\n"|safe + t["function"] | tojson() }}
|
| 23 |
+
{%- else -%}
|
| 24 |
+
{{ "Use the function '"|safe + t["name"] + "' to '"|safe + t["description"] + "'\n"|safe + t | tojson() }}
|
| 25 |
+
{%- endif -%}
|
| 26 |
+
{{- "\n\n" }}
|
| 27 |
+
{%- endfor %}
|
| 28 |
+
{{- '\nThink very carefully before calling functions.\nIf a you choose to call a function ONLY reply in the following format:\n<{start_tag}={function_name}>{parameters}{end_tag}\nwhere\n\nstart_tag => `<function`\nparameters => a JSON dict with the function argument name as key and function argument value as value.\nend_tag => `</function>`\n\nHere is an example,\n<function=example_function_name>{"example_name": "example_value"}</function>\n\nReminder:\n- If looking for real time information use relevant functions before falling back to brave_search\n- Function calls MUST follow the specified format, start with <function= and end with </function>\n- Required parameters MUST be specified\n- Only call one function at a time\n- Put the entire function call reply on one line\n\n' -}}
|
| 29 |
+
{%- endif %}
|
| 30 |
+
{{- "<|eot_id|>" -}}
|
| 31 |
+
|
| 32 |
+
{%- for message in messages -%}
|
| 33 |
+
{%- if message['role'] == 'user' or message['role'] == 'system' -%}
|
| 34 |
+
{{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>' }}
|
| 35 |
+
{%- elif message['role'] == 'tool' -%}
|
| 36 |
+
{{ '<|start_header_id|>ipython<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>' }}
|
| 37 |
+
{%- else -%}
|
| 38 |
+
{{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'}}
|
| 39 |
+
{%- if message['content'] -%}
|
| 40 |
+
{{ message['content'] }}
|
| 41 |
+
{%- endif -%}
|
| 42 |
+
{%- if 'tool_calls' in message and message['tool_calls'] -%}
|
| 43 |
+
{%- for tool_call in message['tool_calls'] -%}
|
| 44 |
+
{%- if tool_call["function"]["name"] == "python" -%}
|
| 45 |
+
{{ '<|python_tag|>' + tool_call['function']['arguments'] }}
|
| 46 |
+
{%- else -%}
|
| 47 |
+
{{ '<function=' + tool_call['function']['name'] + '>' + tool_call['function']['arguments'] + '</function>' }}
|
| 48 |
+
{%- endif -%}
|
| 49 |
+
{%- endfor -%}
|
| 50 |
+
{{ '<|eom_id|>' }}
|
| 51 |
+
{%- else -%}
|
| 52 |
+
{{ '<|eot_id|>' }}
|
| 53 |
+
{%- endif -%}
|
| 54 |
+
{%- endif -%}
|
| 55 |
+
{%- endfor -%}
|
| 56 |
+
{%- if add_generation_prompt -%}
|
| 57 |
+
{{ '<|start_header_id|>assistant<|end_header_id|>\n\n' }}
|
| 58 |
+
{%- endif -%}
|
llama.cpp/models/templates/meetkai-functionary-medium-v3.2.jinja
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{# version=v3.llama3 #}{%- macro append_new_param_info(param_declaration, comment_info, examples_info, depth) -%}
|
| 2 |
+
{%- set offset = "" -%}
|
| 3 |
+
{%- if depth >= 1 -%}
|
| 4 |
+
{%- set offset = " " * depth -%}
|
| 5 |
+
{%- endif -%}
|
| 6 |
+
{%- if comment_info != "<|NONE|>" -%}
|
| 7 |
+
{{ "\n" + offset + comment_info }}
|
| 8 |
+
{%- if examples_info | length > 0 -%}
|
| 9 |
+
{# Append each example info #}
|
| 10 |
+
{%- for example in examples_info -%}
|
| 11 |
+
{{ "\n" + offset + "// " + example|string|replace("'", '"') }}
|
| 12 |
+
{%- endfor -%}
|
| 13 |
+
{%- endif -%}
|
| 14 |
+
{%- endif -%}
|
| 15 |
+
{{ "\n" + offset + param_declaration }}
|
| 16 |
+
{%- endmacro -%}
|
| 17 |
+
|
| 18 |
+
{%- macro convert_data_type(param_type) -%}
|
| 19 |
+
{%- if param_type == "integer" or param_type == "float" -%}
|
| 20 |
+
{{ "number" }}
|
| 21 |
+
{%- else -%}
|
| 22 |
+
{{ param_type }}
|
| 23 |
+
{%- endif -%}
|
| 24 |
+
{%- endmacro -%}
|
| 25 |
+
|
| 26 |
+
{%- macro get_param_type(param) -%}
|
| 27 |
+
{%- set param_type = "any" -%}
|
| 28 |
+
|
| 29 |
+
{%- if "type" in param -%}
|
| 30 |
+
{%- set raw_param_type = param["type"] -%}
|
| 31 |
+
{%- if raw_param_type is iterable and raw_param_type is not string -%}
|
| 32 |
+
{%- set param_type = raw_param_type | join(" | ") -%}
|
| 33 |
+
{%- else -%}
|
| 34 |
+
{%- set param_type = raw_param_type -%}
|
| 35 |
+
{%- endif -%}
|
| 36 |
+
{{ convert_data_type(param_type) }}
|
| 37 |
+
{%- elif "oneOf" in param -%}
|
| 38 |
+
{%- set one_of_types = param["oneOf"]|selectattr("type", "defined")|list -%}
|
| 39 |
+
{%- set one_of_types = one_of_types|map(attribute="type")|unique|list -%}
|
| 40 |
+
{{ convert_data_type(one_of_types | join(" | ")) }}
|
| 41 |
+
{%- endif -%}
|
| 42 |
+
{%- endmacro -%}
|
| 43 |
+
|
| 44 |
+
{%- macro get_format_param(param) -%}
|
| 45 |
+
{%- if "format" in param -%}
|
| 46 |
+
{{ param["format"] }}
|
| 47 |
+
{%- elif "oneOf" in param -%}
|
| 48 |
+
{%- set formats = [] -%}
|
| 49 |
+
{%- for item in param["oneOf"] -%}
|
| 50 |
+
{%- if "format" in item -%}
|
| 51 |
+
{%- if item["format"] == param["oneOf"][-1]["format"] -%}
|
| 52 |
+
{{ item["format"] }}
|
| 53 |
+
{%- else -%}
|
| 54 |
+
{{ item["format"] + " or "}}
|
| 55 |
+
{%- endif -%}
|
| 56 |
+
{%- endif -%}
|
| 57 |
+
{%- endfor -%}
|
| 58 |
+
{%- else -%}
|
| 59 |
+
{{ "<|NONE|>" }}
|
| 60 |
+
{%- endif -%}
|
| 61 |
+
{%- endmacro -%}
|
| 62 |
+
|
| 63 |
+
{%- macro get_param_info(param) -%}
|
| 64 |
+
{%- set param_type = param.get("type", "any") -%}
|
| 65 |
+
{%- set format_param = get_format_param(param) -%}
|
| 66 |
+
|
| 67 |
+
{%- if "description" in param or "default" in param or format_param != "<|NONE|>" or param["maximum"] or param["minimum"] or param["maxLength"] or param["minLength"] -%}
|
| 68 |
+
{{ "//" }}
|
| 69 |
+
{%- if "description" in param -%}
|
| 70 |
+
{%- set desc = param["description"] -%}
|
| 71 |
+
{%- if not desc.endswith(".") -%}
|
| 72 |
+
{%- set desc = desc + "." -%}
|
| 73 |
+
{%- endif -%}
|
| 74 |
+
{{ " " + desc }}
|
| 75 |
+
{%- endif -%}
|
| 76 |
+
|
| 77 |
+
{%- if "default" in param -%}
|
| 78 |
+
{%- set default_value = param["default"] -%}
|
| 79 |
+
{%- if param_type == "string" -%}
|
| 80 |
+
{%- set default_value = '"' ~ default_value ~ '"' -%}
|
| 81 |
+
{%- endif -%}
|
| 82 |
+
{{ " Default=" ~ default_value ~ "." }}
|
| 83 |
+
{%- endif -%}
|
| 84 |
+
|
| 85 |
+
{%- set format_param = get_format_param(param) -%}
|
| 86 |
+
{%- if format_param != "<|NONE|>" -%}
|
| 87 |
+
{{ " Format=" ~ format_param }}
|
| 88 |
+
{%- endif -%}
|
| 89 |
+
|
| 90 |
+
{%- for field, field_name in [("maximum", "Maximum"), ("minimum", "Minimum"), ("maxLength", "Maximum length"), ("minLength", "Minimum length")] -%}
|
| 91 |
+
{%- if field in param -%}
|
| 92 |
+
{{ " " + field_name ~ "=" ~ param[field] }}
|
| 93 |
+
{%- endif -%}
|
| 94 |
+
{%- endfor -%}
|
| 95 |
+
{%- else -%}
|
| 96 |
+
{{ "<|NONE|>"}}
|
| 97 |
+
{%- endif -%}
|
| 98 |
+
{%- endmacro -%}
|
| 99 |
+
|
| 100 |
+
{%- macro get_enum_option_str(enum_options) -%}
|
| 101 |
+
{%- for v in enum_options -%}
|
| 102 |
+
{%- if v is string -%}
|
| 103 |
+
{{ '"' + v + '"' }}
|
| 104 |
+
{%- else -%}
|
| 105 |
+
{{ v }}
|
| 106 |
+
{%- endif -%}
|
| 107 |
+
{%- if enum_options|length > 0 and v != enum_options[-1] -%}
|
| 108 |
+
{{ " | " }}
|
| 109 |
+
{%- endif -%}
|
| 110 |
+
{%- endfor -%}
|
| 111 |
+
{%- endmacro -%}
|
| 112 |
+
|
| 113 |
+
{%- macro get_array_typescript(param_name, param_dic, depth) -%}
|
| 114 |
+
{%- set offset = '' -%}
|
| 115 |
+
{%- if depth >= 1 -%}
|
| 116 |
+
{%- set offset = " " * depth -%}
|
| 117 |
+
{%- endif -%}
|
| 118 |
+
{%- set items_info = param_dic.get('items', {}) -%}
|
| 119 |
+
|
| 120 |
+
{%- if items_info|length == 0 -%}
|
| 121 |
+
{%- if param_name -%}
|
| 122 |
+
{{ "\n" + offset + param_name + ": []" }}
|
| 123 |
+
{%- else -%}
|
| 124 |
+
{{ "\n" + offset + "[]" }}
|
| 125 |
+
{%- endif -%}
|
| 126 |
+
{%- else -%}
|
| 127 |
+
{%- set array_type = get_param_type(items_info) -%}
|
| 128 |
+
{%- if array_type == 'object' -%}
|
| 129 |
+
{%- if param_name -%}
|
| 130 |
+
{{ "\n" + offset + param_name + ": {" }}
|
| 131 |
+
{%- else -%}
|
| 132 |
+
{{ "\n" + offset + "{" }}
|
| 133 |
+
{%- endif -%}
|
| 134 |
+
{{ get_parameter_typescript(items_info.get('properties', {}), items_info.get('required', []), depth + 1) -}}
|
| 135 |
+
{{- "\n" + offset + "}[]" }}
|
| 136 |
+
{%- elif array_type == 'array' -%}
|
| 137 |
+
{%- set item_info = get_array_typescript(None, items_info, depth + 1) -%}
|
| 138 |
+
{%- if not param_name -%}
|
| 139 |
+
{{ "\n" + item_info + "[]" }}
|
| 140 |
+
{%- else -%}
|
| 141 |
+
{{ "\n" + offset + param_name + ": " + item_info|trim + "[]" }}
|
| 142 |
+
{%- endif -%}
|
| 143 |
+
{%- else -%}
|
| 144 |
+
{%- if 'enum' in items_info -%}
|
| 145 |
+
{%- set item_type = get_enum_option_str(items_info['enum']) -%}
|
| 146 |
+
{%- if param_name is none -%}
|
| 147 |
+
{{ "(" + item_type + ")[]"}}
|
| 148 |
+
{%- else -%}
|
| 149 |
+
{{ "\n" + offset + param_name + ": (" + item_type + ")[]" }}
|
| 150 |
+
{%- endif -%}
|
| 151 |
+
{%- else -%}
|
| 152 |
+
{%- if param_name is none -%}
|
| 153 |
+
{{ "\n" + array_type + "[]" }}
|
| 154 |
+
{%- else -%}
|
| 155 |
+
{{ "\n" + offset + param_name + ": " + array_type + "[]," }}
|
| 156 |
+
{%- endif -%}
|
| 157 |
+
{%- endif -%}
|
| 158 |
+
{%- endif -%}
|
| 159 |
+
{%- endif -%}
|
| 160 |
+
{%- endmacro -%}
|
| 161 |
+
|
| 162 |
+
{%- macro get_parameter_typescript(properties, required_params, depth=0) -%}
|
| 163 |
+
{%- set res = "" -%}
|
| 164 |
+
{%- for param_name, param in properties.items() -%}
|
| 165 |
+
{%- if param is mapping -%}
|
| 166 |
+
{%- set comment_info = get_param_info(param) -%}
|
| 167 |
+
{# Param Examples #}
|
| 168 |
+
{%- set examples_info = [] -%}
|
| 169 |
+
{%- if "examples" in param -%}
|
| 170 |
+
{%- set examples_info = ["Example " + param_name + ":"] -%}
|
| 171 |
+
{%- set examples_info = examples_info + param["examples"] -%}
|
| 172 |
+
{%- endif -%}
|
| 173 |
+
|
| 174 |
+
{# Param Name declaration #}
|
| 175 |
+
{%- set param_declaration = param_name -%}
|
| 176 |
+
{%- if required_params is iterable and param_name not in required_params -%}
|
| 177 |
+
{%- set param_declaration = param_declaration + "?" -%}
|
| 178 |
+
{%- endif -%}
|
| 179 |
+
|
| 180 |
+
{%- set param_type = get_param_type(param) -%}
|
| 181 |
+
|
| 182 |
+
{# Handle indentation based on depth #}
|
| 183 |
+
{%- set offset = "" -%}
|
| 184 |
+
{%- if depth >= 1 -%}
|
| 185 |
+
{%- set offset = " " * depth -%}
|
| 186 |
+
{%- endif -%}
|
| 187 |
+
|
| 188 |
+
{%- if param_type == "object" -%}
|
| 189 |
+
{%- if comment_info != "<|NONE|>" -%}
|
| 190 |
+
{{ "\n" + offset + comment_info }}
|
| 191 |
+
{%- endif -%}
|
| 192 |
+
{%- if examples_info|length > 0 -%}
|
| 193 |
+
{%- for example in examples_info -%}
|
| 194 |
+
{{ "\n" + offset + "// " + example|string|replace("'", '"') }}
|
| 195 |
+
{%- endfor -%}
|
| 196 |
+
{%- endif -%}
|
| 197 |
+
{%- set param_declaration = param_declaration + ": {" -%}
|
| 198 |
+
{{ "\n" + offset + param_declaration -}}
|
| 199 |
+
{{- get_parameter_typescript(param.get("properties", {}), param.get("required", []), depth + 1) -}}
|
| 200 |
+
{{- "\n" + offset + "}," }}
|
| 201 |
+
{%- elif param_type == "array" -%}
|
| 202 |
+
{%- set item_info = param.get("items", {}) -%}
|
| 203 |
+
{%- if "type" not in item_info -%}
|
| 204 |
+
{%- set param_declaration = param_declaration + ": []," -%}
|
| 205 |
+
{{ append_new_param_info(param_declaration, comment_info, examples_info, depth) }}
|
| 206 |
+
{%- else -%}
|
| 207 |
+
{%- if comment_info != "<|NONE|>" -%}
|
| 208 |
+
{{ "\n" + offset + comment_info }}
|
| 209 |
+
{%- endif -%}
|
| 210 |
+
{%- if examples_info|length > 0 -%}
|
| 211 |
+
{%- for example in examples_info -%}
|
| 212 |
+
{{ "\n" + offset + "// " + example|string|replace("'", '"') }}
|
| 213 |
+
{%- endfor -%}
|
| 214 |
+
{%- endif -%}
|
| 215 |
+
{%- set array_declaration = get_array_typescript(param_declaration, param, depth) -%}
|
| 216 |
+
{%- if not array_declaration.endswith(",") -%}
|
| 217 |
+
{%- set array_declaration = array_declaration + "," -%}
|
| 218 |
+
{%- endif -%}
|
| 219 |
+
{{ array_declaration}}
|
| 220 |
+
{%- endif -%}
|
| 221 |
+
{%- else -%}
|
| 222 |
+
{%- if "enum" in param -%}
|
| 223 |
+
{%- set param_type = get_enum_option_str(param["enum"]) -%}
|
| 224 |
+
{%- endif -%}
|
| 225 |
+
{%- if "nullable" in param and param["nullable"] -%}
|
| 226 |
+
{%- set param_type = param_type + " | null" -%}
|
| 227 |
+
{%- endif -%}
|
| 228 |
+
{%- set param_declaration = param_declaration + ": " + param_type + "," -%}
|
| 229 |
+
{{ append_new_param_info(param_declaration, comment_info, examples_info, depth) }}
|
| 230 |
+
{%- endif -%}
|
| 231 |
+
{%- endif -%}
|
| 232 |
+
{%- endfor -%}
|
| 233 |
+
{%- endmacro -%}
|
| 234 |
+
|
| 235 |
+
{%- macro generate_schema_from_functions(functions, namespace='functions') -%}
|
| 236 |
+
{{ "// Supported function definitions that should be called when necessary.\n" -}}
|
| 237 |
+
{{- "namespace " + namespace + " {\n\n" -}}
|
| 238 |
+
|
| 239 |
+
{%- for function in functions -%}
|
| 240 |
+
{%- if function.get("function") -%}
|
| 241 |
+
{%- set function = function.get("function") -%}
|
| 242 |
+
{%- endif -%}
|
| 243 |
+
|
| 244 |
+
{%- set function_name = function.get("name") -%}
|
| 245 |
+
{%- if function_name -%}
|
| 246 |
+
{%- set description = function.get('description', '') -%}
|
| 247 |
+
{%- set parameters = function.get('parameters', {}) -%}
|
| 248 |
+
{{- "// " + description + "\n" -}}
|
| 249 |
+
{{- "type " + function_name -}}
|
| 250 |
+
{%- if parameters and parameters.get("properties") -%}
|
| 251 |
+
{{- " = (_: {" -}}
|
| 252 |
+
{%- set required_params = parameters.get("required", []) -%}
|
| 253 |
+
{{ get_parameter_typescript(parameters.get("properties"), required_params, 0) -}}
|
| 254 |
+
{{- "\n}) => any;\n\n" }}
|
| 255 |
+
{%- else -%}
|
| 256 |
+
{{ " = () => any;\n\n" }}
|
| 257 |
+
{%- endif -%}
|
| 258 |
+
{%- endif -%}
|
| 259 |
+
{%- endfor -%}
|
| 260 |
+
{{ "} // namespace " + namespace }}
|
| 261 |
+
{%- endmacro -%}
|
| 262 |
+
{%- if not tools -%}
|
| 263 |
+
{%- set tools = [] -%}
|
| 264 |
+
{%- endif -%}
|
| 265 |
+
{{ bos_token + '<|start_header_id|>system<|end_header_id|>\n\nYou are capable of executing available function(s) if required.\nOnly execute function(s) when absolutely necessary.\nAsk for the required input to:recipient==all\nUse JSON for function arguments.\nRespond in this format:\n>>>${recipient}\n${content}\nAvailable functions:\n' + generate_schema_from_functions(tools) + '<|eot_id|>' -}}
|
| 266 |
+
{%- if tools|length > 0 and tools|selectattr("type", "equalto", "code_interpreter")|list|length > 0 -%}
|
| 267 |
+
{{ '<|start_header_id|>system<|end_header_id|>\n\nWhen you send a message containing Python code to python, it will be executed in a stateful Jupyter notebook environment. python will respond with the output of the execution or time out after 60.0 seconds. The drive at \'/mnt/data\' can be used to save and persist user files.<|eot_id|>' }}
|
| 268 |
+
{%- endif -%}
|
| 269 |
+
{%- for message in messages -%}
|
| 270 |
+
{%- if message['role'] == 'user' or message['role'] == 'system' -%}
|
| 271 |
+
{{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>' }}
|
| 272 |
+
{%- elif message['role'] == 'tool' -%}
|
| 273 |
+
{{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>' }}
|
| 274 |
+
{%- else -%}
|
| 275 |
+
{{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'}}
|
| 276 |
+
{%- if message['content'] -%}
|
| 277 |
+
{{ '>>>all\n' + message['content'] }}
|
| 278 |
+
{%- endif -%}
|
| 279 |
+
{%- if 'tool_calls' in message and message['tool_calls'] -%}
|
| 280 |
+
{%- for tool_call in message['tool_calls'] -%}
|
| 281 |
+
{{ '>>>' + tool_call['function']['name'] + '\n' + tool_call['function']['arguments'] }}
|
| 282 |
+
{%- endfor -%}
|
| 283 |
+
{%- endif -%}
|
| 284 |
+
{{ '<|eot_id|>' }}
|
| 285 |
+
{%- endif -%}
|
| 286 |
+
{%- endfor -%}
|
| 287 |
+
{% if add_generation_prompt %}{{ '<|start_header_id|>assistant<|end_header_id|>\n\n>>>' }}{% endif %}
|
llama.cpp/models/templates/meta-llama-Llama-3.1-8B-Instruct.jinja
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- bos_token }}
|
| 2 |
+
{%- if custom_tools is defined %}
|
| 3 |
+
{%- set tools = custom_tools %}
|
| 4 |
+
{%- endif %}
|
| 5 |
+
{%- if not tools_in_user_message is defined %}
|
| 6 |
+
{%- set tools_in_user_message = true %}
|
| 7 |
+
{%- endif %}
|
| 8 |
+
{%- if not date_string is defined %}
|
| 9 |
+
{%- set date_string = "26 Jul 2024" %}
|
| 10 |
+
{%- endif %}
|
| 11 |
+
{%- if not tools is defined %}
|
| 12 |
+
{%- set tools = none %}
|
| 13 |
+
{%- endif %}
|
| 14 |
+
|
| 15 |
+
{#- This block extracts the system message, so we can slot it into the right place. #}
|
| 16 |
+
{%- if messages[0]['role'] == 'system' %}
|
| 17 |
+
{%- set system_message = messages[0]['content']|trim %}
|
| 18 |
+
{%- set messages = messages[1:] %}
|
| 19 |
+
{%- else %}
|
| 20 |
+
{%- set system_message = "" %}
|
| 21 |
+
{%- endif %}
|
| 22 |
+
|
| 23 |
+
{#- System message + builtin tools #}
|
| 24 |
+
{{- "<|start_header_id|>system<|end_header_id|>\n\n" }}
|
| 25 |
+
{%- if builtin_tools is defined or tools is not none %}
|
| 26 |
+
{{- "Environment: ipython\n" }}
|
| 27 |
+
{%- endif %}
|
| 28 |
+
{%- if builtin_tools is defined %}
|
| 29 |
+
{{- "Tools: " + builtin_tools | reject('equalto', 'code_interpreter') | join(", ") + "\n\n"}}
|
| 30 |
+
{%- endif %}
|
| 31 |
+
{{- "Cutting Knowledge Date: December 2023\n" }}
|
| 32 |
+
{{- "Today Date: " + date_string + "\n\n" }}
|
| 33 |
+
{%- if tools is not none and not tools_in_user_message %}
|
| 34 |
+
{{- "You have access to the following functions. To call a function, please respond with JSON for a function call." }}
|
| 35 |
+
{{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
|
| 36 |
+
{{- "Do not use variables.\n\n" }}
|
| 37 |
+
{%- for t in tools %}
|
| 38 |
+
{{- t | tojson(indent=4) }}
|
| 39 |
+
{{- "\n\n" }}
|
| 40 |
+
{%- endfor %}
|
| 41 |
+
{%- endif %}
|
| 42 |
+
{{- system_message }}
|
| 43 |
+
{{- "<|eot_id|>" }}
|
| 44 |
+
|
| 45 |
+
{#- Custom tools are passed in a user message with some extra guidance #}
|
| 46 |
+
{%- if tools_in_user_message and not tools is none %}
|
| 47 |
+
{#- Extract the first user message so we can plug it in here #}
|
| 48 |
+
{%- if messages | length != 0 %}
|
| 49 |
+
{%- set first_user_message = messages[0]['content']|trim %}
|
| 50 |
+
{%- set messages = messages[1:] %}
|
| 51 |
+
{%- else %}
|
| 52 |
+
{{- raise_exception("Cannot put tools in the first user message when there's no first user message!") }}
|
| 53 |
+
{%- endif %}
|
| 54 |
+
{{- '<|start_header_id|>user<|end_header_id|>\n\n' -}}
|
| 55 |
+
{{- "Given the following functions, please respond with a JSON for a function call " }}
|
| 56 |
+
{{- "with its proper arguments that best answers the given prompt.\n\n" }}
|
| 57 |
+
{{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
|
| 58 |
+
{{- "Do not use variables.\n\n" }}
|
| 59 |
+
{%- for t in tools %}
|
| 60 |
+
{{- t | tojson(indent=4) }}
|
| 61 |
+
{{- "\n\n" }}
|
| 62 |
+
{%- endfor %}
|
| 63 |
+
{{- first_user_message + "<|eot_id|>"}}
|
| 64 |
+
{%- endif %}
|
| 65 |
+
|
| 66 |
+
{%- for message in messages %}
|
| 67 |
+
{%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %}
|
| 68 |
+
{{- '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'+ message['content'] | trim + '<|eot_id|>' }}
|
| 69 |
+
{%- elif 'tool_calls' in message %}
|
| 70 |
+
{%- if not message.tool_calls|length == 1 %}
|
| 71 |
+
{{- raise_exception("This model only supports single tool-calls at once!") }}
|
| 72 |
+
{%- endif %}
|
| 73 |
+
{%- set tool_call = message.tool_calls[0].function %}
|
| 74 |
+
{%- if builtin_tools is defined and tool_call.name in builtin_tools %}
|
| 75 |
+
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
|
| 76 |
+
{{- "<|python_tag|>" + tool_call.name + ".call(" }}
|
| 77 |
+
{%- for arg_name, arg_val in tool_call.arguments | items %}
|
| 78 |
+
{{- arg_name + '="' + arg_val + '"' }}
|
| 79 |
+
{%- if not loop.last %}
|
| 80 |
+
{{- ", " }}
|
| 81 |
+
{%- endif %}
|
| 82 |
+
{%- endfor %}
|
| 83 |
+
{{- ")" }}
|
| 84 |
+
{%- else %}
|
| 85 |
+
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
|
| 86 |
+
{{- '{"name": "' + tool_call.name + '", ' }}
|
| 87 |
+
{{- '"parameters": ' }}
|
| 88 |
+
{{- tool_call.arguments | tojson }}
|
| 89 |
+
{{- "}" }}
|
| 90 |
+
{%- endif %}
|
| 91 |
+
{%- if builtin_tools is defined %}
|
| 92 |
+
{#- This means we're in ipython mode #}
|
| 93 |
+
{{- "<|eom_id|>" }}
|
| 94 |
+
{%- else %}
|
| 95 |
+
{{- "<|eot_id|>" }}
|
| 96 |
+
{%- endif %}
|
| 97 |
+
{%- elif message.role == "tool" or message.role == "ipython" %}
|
| 98 |
+
{{- "<|start_header_id|>ipython<|end_header_id|>\n\n" }}
|
| 99 |
+
{%- if message.content is mapping or message.content is iterable %}
|
| 100 |
+
{{- message.content | tojson }}
|
| 101 |
+
{%- else %}
|
| 102 |
+
{{- message.content }}
|
| 103 |
+
{%- endif %}
|
| 104 |
+
{{- "<|eot_id|>" }}
|
| 105 |
+
{%- endif %}
|
| 106 |
+
{%- endfor %}
|
| 107 |
+
{%- if add_generation_prompt %}
|
| 108 |
+
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' }}
|
| 109 |
+
{%- endif %}
|
llama.cpp/models/templates/meta-llama-Llama-3.2-3B-Instruct.jinja
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- bos_token }}
|
| 2 |
+
{%- if custom_tools is defined %}
|
| 3 |
+
{%- set tools = custom_tools %}
|
| 4 |
+
{%- endif %}
|
| 5 |
+
{%- if not tools_in_user_message is defined %}
|
| 6 |
+
{%- set tools_in_user_message = true %}
|
| 7 |
+
{%- endif %}
|
| 8 |
+
{%- if not date_string is defined %}
|
| 9 |
+
{%- if strftime_now is defined %}
|
| 10 |
+
{%- set date_string = strftime_now("%d %b %Y") %}
|
| 11 |
+
{%- else %}
|
| 12 |
+
{%- set date_string = "26 Jul 2024" %}
|
| 13 |
+
{%- endif %}
|
| 14 |
+
{%- endif %}
|
| 15 |
+
{%- if not tools is defined %}
|
| 16 |
+
{%- set tools = none %}
|
| 17 |
+
{%- endif %}
|
| 18 |
+
|
| 19 |
+
{#- This block extracts the system message, so we can slot it into the right place. #}
|
| 20 |
+
{%- if messages[0]['role'] == 'system' %}
|
| 21 |
+
{%- set system_message = messages[0]['content']|trim %}
|
| 22 |
+
{%- set messages = messages[1:] %}
|
| 23 |
+
{%- else %}
|
| 24 |
+
{%- set system_message = "" %}
|
| 25 |
+
{%- endif %}
|
| 26 |
+
|
| 27 |
+
{#- System message #}
|
| 28 |
+
{{- "<|start_header_id|>system<|end_header_id|>\n\n" }}
|
| 29 |
+
{%- if tools is not none %}
|
| 30 |
+
{{- "Environment: ipython\n" }}
|
| 31 |
+
{%- endif %}
|
| 32 |
+
{{- "Cutting Knowledge Date: December 2023\n" }}
|
| 33 |
+
{{- "Today Date: " + date_string + "\n\n" }}
|
| 34 |
+
{%- if tools is not none and not tools_in_user_message %}
|
| 35 |
+
{{- "You have access to the following functions. To call a function, please respond with JSON for a function call." }}
|
| 36 |
+
{{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
|
| 37 |
+
{{- "Do not use variables.\n\n" }}
|
| 38 |
+
{%- for t in tools %}
|
| 39 |
+
{{- t | tojson(indent=4) }}
|
| 40 |
+
{{- "\n\n" }}
|
| 41 |
+
{%- endfor %}
|
| 42 |
+
{%- endif %}
|
| 43 |
+
{{- system_message }}
|
| 44 |
+
{{- "<|eot_id|>" }}
|
| 45 |
+
|
| 46 |
+
{#- Custom tools are passed in a user message with some extra guidance #}
|
| 47 |
+
{%- if tools_in_user_message and not tools is none %}
|
| 48 |
+
{#- Extract the first user message so we can plug it in here #}
|
| 49 |
+
{%- if messages | length != 0 %}
|
| 50 |
+
{%- set first_user_message = messages[0]['content']|trim %}
|
| 51 |
+
{%- set messages = messages[1:] %}
|
| 52 |
+
{%- else %}
|
| 53 |
+
{{- raise_exception("Cannot put tools in the first user message when there's no first user message!") }}
|
| 54 |
+
{%- endif %}
|
| 55 |
+
{{- '<|start_header_id|>user<|end_header_id|>\n\n' -}}
|
| 56 |
+
{{- "Given the following functions, please respond with a JSON for a function call " }}
|
| 57 |
+
{{- "with its proper arguments that best answers the given prompt.\n\n" }}
|
| 58 |
+
{{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
|
| 59 |
+
{{- "Do not use variables.\n\n" }}
|
| 60 |
+
{%- for t in tools %}
|
| 61 |
+
{{- t | tojson(indent=4) }}
|
| 62 |
+
{{- "\n\n" }}
|
| 63 |
+
{%- endfor %}
|
| 64 |
+
{{- first_user_message + "<|eot_id|>"}}
|
| 65 |
+
{%- endif %}
|
| 66 |
+
|
| 67 |
+
{%- for message in messages %}
|
| 68 |
+
{%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %}
|
| 69 |
+
{{- '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'+ message['content'] | trim + '<|eot_id|>' }}
|
| 70 |
+
{%- elif 'tool_calls' in message %}
|
| 71 |
+
{%- if not message.tool_calls|length == 1 %}
|
| 72 |
+
{{- raise_exception("This model only supports single tool-calls at once!") }}
|
| 73 |
+
{%- endif %}
|
| 74 |
+
{%- set tool_call = message.tool_calls[0].function %}
|
| 75 |
+
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
|
| 76 |
+
{{- '{"name": "' + tool_call.name + '", ' }}
|
| 77 |
+
{{- '"parameters": ' }}
|
| 78 |
+
{{- tool_call.arguments | tojson }}
|
| 79 |
+
{{- "}" }}
|
| 80 |
+
{{- "<|eot_id|>" }}
|
| 81 |
+
{%- elif message.role == "tool" or message.role == "ipython" %}
|
| 82 |
+
{{- "<|start_header_id|>ipython<|end_header_id|>\n\n" }}
|
| 83 |
+
{%- if message.content is mapping or message.content is iterable %}
|
| 84 |
+
{{- message.content | tojson }}
|
| 85 |
+
{%- else %}
|
| 86 |
+
{{- message.content }}
|
| 87 |
+
{%- endif %}
|
| 88 |
+
{{- "<|eot_id|>" }}
|
| 89 |
+
{%- endif %}
|
| 90 |
+
{%- endfor %}
|
| 91 |
+
{%- if add_generation_prompt %}
|
| 92 |
+
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' }}
|
| 93 |
+
{%- endif %}
|
llama.cpp/models/templates/meta-llama-Llama-3.3-70B-Instruct.jinja
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- bos_token }}
|
| 2 |
+
{%- if custom_tools is defined %}
|
| 3 |
+
{%- set tools = custom_tools %}
|
| 4 |
+
{%- endif %}
|
| 5 |
+
{%- if not tools_in_user_message is defined %}
|
| 6 |
+
{%- set tools_in_user_message = true %}
|
| 7 |
+
{%- endif %}
|
| 8 |
+
{%- if not date_string is defined %}
|
| 9 |
+
{%- set date_string = "26 Jul 2024" %}
|
| 10 |
+
{%- endif %}
|
| 11 |
+
{%- if not tools is defined %}
|
| 12 |
+
{%- set tools = none %}
|
| 13 |
+
{%- endif %}
|
| 14 |
+
|
| 15 |
+
{#- This block extracts the system message, so we can slot it into the right place. #}
|
| 16 |
+
{%- if messages[0]['role'] == 'system' %}
|
| 17 |
+
{%- set system_message = messages[0]['content']|trim %}
|
| 18 |
+
{%- set messages = messages[1:] %}
|
| 19 |
+
{%- else %}
|
| 20 |
+
{%- set system_message = "" %}
|
| 21 |
+
{%- endif %}
|
| 22 |
+
|
| 23 |
+
{#- System message + builtin tools #}
|
| 24 |
+
{{- "<|start_header_id|>system<|end_header_id|>\n\n" }}
|
| 25 |
+
{%- if builtin_tools is defined or tools is not none %}
|
| 26 |
+
{{- "Environment: ipython\n" }}
|
| 27 |
+
{%- endif %}
|
| 28 |
+
{%- if builtin_tools is defined %}
|
| 29 |
+
{{- "Tools: " + builtin_tools | reject('equalto', 'code_interpreter') | join(", ") + "\n\n"}}
|
| 30 |
+
{%- endif %}
|
| 31 |
+
{{- "Cutting Knowledge Date: December 2023\n" }}
|
| 32 |
+
{{- "Today Date: " + date_string + "\n\n" }}
|
| 33 |
+
{%- if tools is not none and not tools_in_user_message %}
|
| 34 |
+
{{- "You have access to the following functions. To call a function, please respond with JSON for a function call." }}
|
| 35 |
+
{{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
|
| 36 |
+
{{- "Do not use variables.\n\n" }}
|
| 37 |
+
{%- for t in tools %}
|
| 38 |
+
{{- t | tojson(indent=4) }}
|
| 39 |
+
{{- "\n\n" }}
|
| 40 |
+
{%- endfor %}
|
| 41 |
+
{%- endif %}
|
| 42 |
+
{{- system_message }}
|
| 43 |
+
{{- "<|eot_id|>" }}
|
| 44 |
+
|
| 45 |
+
{#- Custom tools are passed in a user message with some extra guidance #}
|
| 46 |
+
{%- if tools_in_user_message and not tools is none %}
|
| 47 |
+
{#- Extract the first user message so we can plug it in here #}
|
| 48 |
+
{%- if messages | length != 0 %}
|
| 49 |
+
{%- set first_user_message = messages[0]['content']|trim %}
|
| 50 |
+
{%- set messages = messages[1:] %}
|
| 51 |
+
{%- else %}
|
| 52 |
+
{{- raise_exception("Cannot put tools in the first user message when there's no first user message!") }}
|
| 53 |
+
{%- endif %}
|
| 54 |
+
{{- '<|start_header_id|>user<|end_header_id|>\n\n' -}}
|
| 55 |
+
{{- "Given the following functions, please respond with a JSON for a function call " }}
|
| 56 |
+
{{- "with its proper arguments that best answers the given prompt.\n\n" }}
|
| 57 |
+
{{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
|
| 58 |
+
{{- "Do not use variables.\n\n" }}
|
| 59 |
+
{%- for t in tools %}
|
| 60 |
+
{{- t | tojson(indent=4) }}
|
| 61 |
+
{{- "\n\n" }}
|
| 62 |
+
{%- endfor %}
|
| 63 |
+
{{- first_user_message + "<|eot_id|>"}}
|
| 64 |
+
{%- endif %}
|
| 65 |
+
|
| 66 |
+
{%- for message in messages %}
|
| 67 |
+
{%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %}
|
| 68 |
+
{{- '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'+ message['content'] | trim + '<|eot_id|>' }}
|
| 69 |
+
{%- elif 'tool_calls' in message %}
|
| 70 |
+
{%- if not message.tool_calls|length == 1 %}
|
| 71 |
+
{{- raise_exception("This model only supports single tool-calls at once!") }}
|
| 72 |
+
{%- endif %}
|
| 73 |
+
{%- set tool_call = message.tool_calls[0].function %}
|
| 74 |
+
{%- if builtin_tools is defined and tool_call.name in builtin_tools %}
|
| 75 |
+
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
|
| 76 |
+
{{- "<|python_tag|>" + tool_call.name + ".call(" }}
|
| 77 |
+
{%- for arg_name, arg_val in tool_call.arguments | items %}
|
| 78 |
+
{{- arg_name + '="' + arg_val + '"' }}
|
| 79 |
+
{%- if not loop.last %}
|
| 80 |
+
{{- ", " }}
|
| 81 |
+
{%- endif %}
|
| 82 |
+
{%- endfor %}
|
| 83 |
+
{{- ")" }}
|
| 84 |
+
{%- else %}
|
| 85 |
+
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
|
| 86 |
+
{{- '{"name": "' + tool_call.name + '", ' }}
|
| 87 |
+
{{- '"parameters": ' }}
|
| 88 |
+
{{- tool_call.arguments | tojson }}
|
| 89 |
+
{{- "}" }}
|
| 90 |
+
{%- endif %}
|
| 91 |
+
{%- if builtin_tools is defined %}
|
| 92 |
+
{#- This means we're in ipython mode #}
|
| 93 |
+
{{- "<|eom_id|>" }}
|
| 94 |
+
{%- else %}
|
| 95 |
+
{{- "<|eot_id|>" }}
|
| 96 |
+
{%- endif %}
|
| 97 |
+
{%- elif message.role == "tool" or message.role == "ipython" %}
|
| 98 |
+
{{- "<|start_header_id|>ipython<|end_header_id|>\n\n" }}
|
| 99 |
+
{%- if message.content is mapping or message.content is iterable %}
|
| 100 |
+
{{- message.content | tojson }}
|
| 101 |
+
{%- else %}
|
| 102 |
+
{{- message.content }}
|
| 103 |
+
{%- endif %}
|
| 104 |
+
{{- "<|eot_id|>" }}
|
| 105 |
+
{%- endif %}
|
| 106 |
+
{%- endfor %}
|
| 107 |
+
{%- if add_generation_prompt %}
|
| 108 |
+
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' }}
|
| 109 |
+
{%- endif %}
|
llama.cpp/models/templates/microsoft-Phi-3.5-mini-instruct.jinja
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% for message in messages %}{% if message['role'] == 'system' and message['content'] %}{{'<|system|>
|
| 2 |
+
' + message['content'] + '<|end|>
|
| 3 |
+
'}}{% elif message['role'] == 'user' %}{{'<|user|>
|
| 4 |
+
' + message['content'] + '<|end|>
|
| 5 |
+
'}}{% elif message['role'] == 'assistant' %}{{'<|assistant|>
|
| 6 |
+
' + message['content'] + '<|end|>
|
| 7 |
+
'}}{% endif %}{% endfor %}{% if add_generation_prompt %}{{ '<|assistant|>
|
| 8 |
+
' }}{% else %}{{ eos_token }}{% endif %}
|
llama.cpp/pocs/vdot/CMakeLists.txt
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
set(TARGET llama-vdot)
|
| 2 |
+
add_executable(${TARGET} vdot.cpp)
|
| 3 |
+
target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT})
|
| 4 |
+
target_compile_features(${TARGET} PRIVATE cxx_std_17)
|
| 5 |
+
|
| 6 |
+
set(TARGET llama-q8dot)
|
| 7 |
+
add_executable(${TARGET} q8dot.cpp)
|
| 8 |
+
target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT})
|
| 9 |
+
target_compile_features(${TARGET} PRIVATE cxx_std_17)
|
llama.cpp/pocs/vdot/q8dot.cpp
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <cstdio>
|
| 2 |
+
#include <type_traits>
|
| 3 |
+
#include <vector>
|
| 4 |
+
#include <random>
|
| 5 |
+
#include <chrono>
|
| 6 |
+
#include <cstdlib>
|
| 7 |
+
#include <cmath>
|
| 8 |
+
#include <cassert>
|
| 9 |
+
#include <cstring>
|
| 10 |
+
#include <array>
|
| 11 |
+
#include <type_traits>
|
| 12 |
+
|
| 13 |
+
#include <ggml.h>
|
| 14 |
+
#include <ggml-cpu.h>
|
| 15 |
+
|
| 16 |
+
constexpr int kVecSize = 1 << 16;
|
| 17 |
+
|
| 18 |
+
// Copy-pasted from ggml.c
|
| 19 |
+
#define QK4_0 32
|
| 20 |
+
typedef struct {
|
| 21 |
+
float d; // delta
|
| 22 |
+
uint8_t qs[QK4_0 / 2]; // nibbles / quants
|
| 23 |
+
} block_q4_0;
|
| 24 |
+
static_assert(sizeof(block_q4_0) == sizeof(float) + QK4_0 / 2, "wrong q4_0 block size/padding");
|
| 25 |
+
|
| 26 |
+
#define QK4_1 32
|
| 27 |
+
typedef struct {
|
| 28 |
+
float d; // delta
|
| 29 |
+
float m; // min
|
| 30 |
+
uint8_t qs[QK4_1 / 2]; // nibbles / quants
|
| 31 |
+
} block_q4_1;
|
| 32 |
+
static_assert(sizeof(block_q4_1) == sizeof(float) * 2 + QK4_1 / 2, "wrong q4_1 block size/padding");
|
| 33 |
+
|
| 34 |
+
// Copy-pasted from ggml.c
|
| 35 |
+
#define QK8_0 32
|
| 36 |
+
typedef struct {
|
| 37 |
+
float d; // delta
|
| 38 |
+
float s; // d * sum(qs[i])
|
| 39 |
+
int8_t qs[QK8_0]; // quants
|
| 40 |
+
} block_q8_0;
|
| 41 |
+
static_assert(sizeof(block_q8_0) == 2*sizeof(float) + QK8_0, "wrong q8_0 block size/padding");
|
| 42 |
+
|
| 43 |
+
static_assert(QK4_1 == QK8_0, "QK4_1 and QK8_0 must be the same");
|
| 44 |
+
static_assert(QK4_0 == QK8_0, "QK4_0 and QK8_0 must be the same");
|
| 45 |
+
|
| 46 |
+
template <typename T>
|
| 47 |
+
static void fillQ4blocks(std::vector<T>& blocks, std::mt19937& rndm) {
|
| 48 |
+
for (auto& b : blocks) {
|
| 49 |
+
b.d = 1;
|
| 50 |
+
for (int i=0; i<QK4_1/2; ++i) {
|
| 51 |
+
uint8_t v1 = rndm() >> 28;
|
| 52 |
+
uint8_t v2 = rndm() >> 28;
|
| 53 |
+
b.qs[i] = v1 | (v2 << 4);
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
static void fillQ80blocks(std::vector<block_q8_0>& blocks, std::mt19937& rndm) {
|
| 59 |
+
for (auto& b : blocks) {
|
| 60 |
+
b.d = 1;
|
| 61 |
+
int sum = 0;
|
| 62 |
+
for (int i=0; i<QK8_0; ++i) {
|
| 63 |
+
b.qs[i] = (rndm() >> 24) - 128;
|
| 64 |
+
sum += b.qs[i];
|
| 65 |
+
}
|
| 66 |
+
b.s = b.d * sum;
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
static float simpleDot(const block_q4_0& x, const block_q8_0& y) {
|
| 71 |
+
int s1 = 0; //, s2 = 0;
|
| 72 |
+
for (int i=0; i<QK4_1/2; i+=2) {
|
| 73 |
+
int v1 = x.qs[i+0] & 0xf;
|
| 74 |
+
int v2 = x.qs[i+0] >> 4;
|
| 75 |
+
int v3 = x.qs[i+1] & 0xf;
|
| 76 |
+
int v4 = x.qs[i+1] >> 4;
|
| 77 |
+
int j = 2*i;
|
| 78 |
+
s1 += v1*y.qs[j] + v2*y.qs[j+1] + v3*y.qs[j+2] + v4*y.qs[j+3];
|
| 79 |
+
//s2 += y.qs[j] + y.qs[j+1] + y.qs[j+2] + y.qs[j+3];
|
| 80 |
+
}
|
| 81 |
+
return y.d * x.d * s1 - 8 * x.d * y.s;
|
| 82 |
+
//return y.d * x.d * (s1 - 8 * s2);
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
static float simpleDot(const block_q4_1& x, const block_q8_0& y) {
|
| 86 |
+
int s1 = 0; //, s2 = 0;
|
| 87 |
+
for (int i=0; i<QK4_1/2; i+=2) {
|
| 88 |
+
int v1 = x.qs[i+0] & 0xf;
|
| 89 |
+
int v2 = x.qs[i+0] >> 4;
|
| 90 |
+
int v3 = x.qs[i+1] & 0xf;
|
| 91 |
+
int v4 = x.qs[i+1] >> 4;
|
| 92 |
+
int j = 2*i;
|
| 93 |
+
s1 += v1*y.qs[j] + v2*y.qs[j+1] + v3*y.qs[j+2] + v4*y.qs[j+3];
|
| 94 |
+
//s2 += y.qs[j] + y.qs[j+1] + y.qs[j+2] + y.qs[j+3];
|
| 95 |
+
}
|
| 96 |
+
return y.d * x.d * s1 + y.s * x.m;
|
| 97 |
+
//return y.d * (x.d * s1 + x.m * s2);
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
struct Stat {
|
| 101 |
+
double sum = 0, sumt = 0, sumt2 = 0, maxt = 0;
|
| 102 |
+
int nloop = 0;
|
| 103 |
+
void addResult(double s, double t) {
|
| 104 |
+
sum += s;
|
| 105 |
+
sumt += t; sumt2 += t*t; maxt = std::max(maxt, t);
|
| 106 |
+
++nloop;
|
| 107 |
+
}
|
| 108 |
+
void reportResult(const char* title) const {
|
| 109 |
+
if (nloop < 1) {
|
| 110 |
+
printf("%s(%s): no result\n",__func__,title);
|
| 111 |
+
return;
|
| 112 |
+
}
|
| 113 |
+
printf("============ %s\n",title);
|
| 114 |
+
printf("<dot> = %g\n",sum/nloop);
|
| 115 |
+
auto t = sumt/nloop, dt = sumt2/nloop - t*t;
|
| 116 |
+
if (dt > 0) dt = sqrt(dt);
|
| 117 |
+
printf("<time> = %g +/- %g us. Max. time = %g us.\n",t,dt,maxt);
|
| 118 |
+
}
|
| 119 |
+
};
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
int main(int argc, char** argv) {
|
| 123 |
+
|
| 124 |
+
int nloop = argc > 1 ? atoi(argv[1]) : 10;
|
| 125 |
+
int type = argc > 2 ? atoi(argv[2]) : 1;
|
| 126 |
+
|
| 127 |
+
std::mt19937 rndm(1234);
|
| 128 |
+
|
| 129 |
+
std::vector<block_q4_1> x41;
|
| 130 |
+
std::vector<block_q4_0> x40;
|
| 131 |
+
std::vector<block_q8_0> y(kVecSize);
|
| 132 |
+
if (type == 0) x40.resize(kVecSize);
|
| 133 |
+
else {
|
| 134 |
+
x41.resize(kVecSize);
|
| 135 |
+
for (auto& b : x41) b.m = 1;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
auto ggml_type = type == 0 ? GGML_TYPE_Q4_0 : GGML_TYPE_Q4_1;
|
| 139 |
+
|
| 140 |
+
const auto * funcs = ggml_get_type_traits_cpu(ggml_type);
|
| 141 |
+
|
| 142 |
+
Stat simple, ggml;
|
| 143 |
+
|
| 144 |
+
for (int iloop=0; iloop<nloop; ++iloop) {
|
| 145 |
+
|
| 146 |
+
if (type == 0) fillQ4blocks(x40, rndm);
|
| 147 |
+
else fillQ4blocks(x41, rndm);
|
| 148 |
+
fillQ80blocks(y, rndm);
|
| 149 |
+
|
| 150 |
+
auto t1 = std::chrono::high_resolution_clock::now();
|
| 151 |
+
double s = 0;
|
| 152 |
+
if (type == 0) for (int i=0; i<kVecSize; ++i) s += simpleDot(x40[i], y[i]);
|
| 153 |
+
else for (int i=0; i<kVecSize; ++i) s += simpleDot(x41[i], y[i]);
|
| 154 |
+
auto t2 = std::chrono::high_resolution_clock::now();
|
| 155 |
+
auto t = 1e-3*std::chrono::duration_cast<std::chrono::nanoseconds>(t2-t1).count();
|
| 156 |
+
if (iloop > 3) simple.addResult(s, t);
|
| 157 |
+
|
| 158 |
+
t1 = std::chrono::high_resolution_clock::now();
|
| 159 |
+
float fs;
|
| 160 |
+
if (type == 0) funcs->vec_dot(kVecSize * QK4_1, &fs, 0, x40.data(), 0, y.data(), 0, 1);
|
| 161 |
+
else funcs->vec_dot(kVecSize * QK4_1, &fs, 0, x41.data(), 0, y.data(), 0, 1);
|
| 162 |
+
t2 = std::chrono::high_resolution_clock::now();
|
| 163 |
+
t = 1e-3*std::chrono::duration_cast<std::chrono::nanoseconds>(t2-t1).count();
|
| 164 |
+
if (iloop > 3) ggml.addResult(fs, t);
|
| 165 |
+
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
// Report the time (and the average of the dot products so the compiler does not come up with the idea
|
| 169 |
+
// of optimizing away the function calls after figuring that the result is not used).
|
| 170 |
+
simple.reportResult("Simple");
|
| 171 |
+
ggml.reportResult("ggml");
|
| 172 |
+
return 0;
|
| 173 |
+
}
|
llama.cpp/pocs/vdot/vdot.cpp
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <cstdio>
|
| 2 |
+
#include <vector>
|
| 3 |
+
#include <random>
|
| 4 |
+
#include <chrono>
|
| 5 |
+
#include <cstdlib>
|
| 6 |
+
#include <cmath>
|
| 7 |
+
#include <cassert>
|
| 8 |
+
#include <cstring>
|
| 9 |
+
#include <array>
|
| 10 |
+
|
| 11 |
+
#include <ggml.h>
|
| 12 |
+
#include <ggml-cpu.h>
|
| 13 |
+
|
| 14 |
+
#if defined(_MSC_VER)
|
| 15 |
+
#pragma warning(disable: 4244 4267) // possible loss of data
|
| 16 |
+
#endif
|
| 17 |
+
|
| 18 |
+
constexpr int kVecSize = 1 << 18;
|
| 19 |
+
|
| 20 |
+
static float drawFromGaussianPdf(std::mt19937& rndm) {
|
| 21 |
+
constexpr double kScale = 1./(1. + std::mt19937::max());
|
| 22 |
+
constexpr double kTwoPiTimesScale = 6.28318530717958647692*kScale;
|
| 23 |
+
static float lastX;
|
| 24 |
+
static bool haveX = false;
|
| 25 |
+
if (haveX) { haveX = false; return lastX; }
|
| 26 |
+
auto r = sqrt(-2*log(1 - kScale*rndm()));
|
| 27 |
+
auto phi = kTwoPiTimesScale * rndm();
|
| 28 |
+
lastX = r*sin(phi);
|
| 29 |
+
haveX = true;
|
| 30 |
+
return r*cos(phi);
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
static void fillRandomGaussianFloats(std::vector<float>& values, std::mt19937& rndm, float mean = 0) {
|
| 34 |
+
for (auto& v : values) v = mean + drawFromGaussianPdf(rndm);
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
// Copy-pasted from ggml.c
|
| 38 |
+
#define QK4_0 32
|
| 39 |
+
typedef struct {
|
| 40 |
+
float d; // delta
|
| 41 |
+
uint8_t qs[QK4_0 / 2]; // nibbles / quants
|
| 42 |
+
} block_q4_0;
|
| 43 |
+
static_assert(sizeof(block_q4_0) == sizeof(float) + QK4_0 / 2, "wrong q4_0 block size/padding");
|
| 44 |
+
|
| 45 |
+
#define QK4_1 32
|
| 46 |
+
typedef struct {
|
| 47 |
+
float d; // delta
|
| 48 |
+
float m; // min
|
| 49 |
+
uint8_t qs[QK4_1 / 2]; // nibbles / quants
|
| 50 |
+
} block_q4_1;
|
| 51 |
+
static_assert(sizeof(block_q4_1) == sizeof(float) * 2 + QK4_1 / 2, "wrong q4_1 block size/padding");
|
| 52 |
+
|
| 53 |
+
// Copy-pasted from ggml.c
|
| 54 |
+
#define QK8_0 32
|
| 55 |
+
typedef struct {
|
| 56 |
+
float d; // delta
|
| 57 |
+
int8_t qs[QK8_0]; // quants
|
| 58 |
+
} block_q8_0;
|
| 59 |
+
static_assert(sizeof(block_q8_0) == sizeof(float) + QK8_0, "wrong q8_0 block size/padding");
|
| 60 |
+
|
| 61 |
+
// "Scalar" dot product between the quantized vector x and float vector y
|
| 62 |
+
inline double dot(int n, const block_q4_0* x, const float* y) {
|
| 63 |
+
const static float kValues[16] = {-8.f, -7.f, -6.f, -5.f, -4.f, -3.f, -2.f, -1.f, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f};
|
| 64 |
+
constexpr uint32_t kMask1 = 0x0f0f0f0f;
|
| 65 |
+
uint32_t u1, u2;
|
| 66 |
+
auto q1 = (const uint8_t*)&u1;
|
| 67 |
+
auto q2 = (const uint8_t*)&u2;
|
| 68 |
+
double sum = 0;
|
| 69 |
+
for (int i=0; i<n; ++i) {
|
| 70 |
+
float d = x->d;
|
| 71 |
+
auto u = (const uint32_t*)x->qs;
|
| 72 |
+
float s = 0;
|
| 73 |
+
for (int k=0; k<4; ++k) {
|
| 74 |
+
u1 = u[k] & kMask1;
|
| 75 |
+
u2 = (u[k] >> 4) & kMask1;
|
| 76 |
+
s += y[0]*kValues[q1[0]] + y[1]*kValues[q2[0]] +
|
| 77 |
+
y[2]*kValues[q1[1]] + y[3]*kValues[q2[1]] +
|
| 78 |
+
y[4]*kValues[q1[2]] + y[5]*kValues[q2[2]] +
|
| 79 |
+
y[6]*kValues[q1[3]] + y[7]*kValues[q2[3]];
|
| 80 |
+
y += 8;
|
| 81 |
+
}
|
| 82 |
+
sum += s*d;
|
| 83 |
+
++x;
|
| 84 |
+
}
|
| 85 |
+
return sum;
|
| 86 |
+
}
|
| 87 |
+
// Alternative version of the above. Faster on my Mac (~45 us vs ~55 us per dot product),
|
| 88 |
+
// but about the same on X86_64 (Ryzen 7950X CPU).
|
| 89 |
+
inline double dot3(int n, const block_q4_0* x, const float* y) {
|
| 90 |
+
const static std::pair<float,float> kValues[256] = {
|
| 91 |
+
{-8.f, -8.f}, {-7.f, -8.f}, {-6.f, -8.f}, {-5.f, -8.f}, {-4.f, -8.f}, {-3.f, -8.f}, {-2.f, -8.f}, {-1.f, -8.f},
|
| 92 |
+
{ 0.f, -8.f}, { 1.f, -8.f}, { 2.f, -8.f}, { 3.f, -8.f}, { 4.f, -8.f}, { 5.f, -8.f}, { 6.f, -8.f}, { 7.f, -8.f},
|
| 93 |
+
{-8.f, -7.f}, {-7.f, -7.f}, {-6.f, -7.f}, {-5.f, -7.f}, {-4.f, -7.f}, {-3.f, -7.f}, {-2.f, -7.f}, {-1.f, -7.f},
|
| 94 |
+
{ 0.f, -7.f}, { 1.f, -7.f}, { 2.f, -7.f}, { 3.f, -7.f}, { 4.f, -7.f}, { 5.f, -7.f}, { 6.f, -7.f}, { 7.f, -7.f},
|
| 95 |
+
{-8.f, -6.f}, {-7.f, -6.f}, {-6.f, -6.f}, {-5.f, -6.f}, {-4.f, -6.f}, {-3.f, -6.f}, {-2.f, -6.f}, {-1.f, -6.f},
|
| 96 |
+
{ 0.f, -6.f}, { 1.f, -6.f}, { 2.f, -6.f}, { 3.f, -6.f}, { 4.f, -6.f}, { 5.f, -6.f}, { 6.f, -6.f}, { 7.f, -6.f},
|
| 97 |
+
{-8.f, -5.f}, {-7.f, -5.f}, {-6.f, -5.f}, {-5.f, -5.f}, {-4.f, -5.f}, {-3.f, -5.f}, {-2.f, -5.f}, {-1.f, -5.f},
|
| 98 |
+
{ 0.f, -5.f}, { 1.f, -5.f}, { 2.f, -5.f}, { 3.f, -5.f}, { 4.f, -5.f}, { 5.f, -5.f}, { 6.f, -5.f}, { 7.f, -5.f},
|
| 99 |
+
{-8.f, -4.f}, {-7.f, -4.f}, {-6.f, -4.f}, {-5.f, -4.f}, {-4.f, -4.f}, {-3.f, -4.f}, {-2.f, -4.f}, {-1.f, -4.f},
|
| 100 |
+
{ 0.f, -4.f}, { 1.f, -4.f}, { 2.f, -4.f}, { 3.f, -4.f}, { 4.f, -4.f}, { 5.f, -4.f}, { 6.f, -4.f}, { 7.f, -4.f},
|
| 101 |
+
{-8.f, -3.f}, {-7.f, -3.f}, {-6.f, -3.f}, {-5.f, -3.f}, {-4.f, -3.f}, {-3.f, -3.f}, {-2.f, -3.f}, {-1.f, -3.f},
|
| 102 |
+
{ 0.f, -3.f}, { 1.f, -3.f}, { 2.f, -3.f}, { 3.f, -3.f}, { 4.f, -3.f}, { 5.f, -3.f}, { 6.f, -3.f}, { 7.f, -3.f},
|
| 103 |
+
{-8.f, -2.f}, {-7.f, -2.f}, {-6.f, -2.f}, {-5.f, -2.f}, {-4.f, -2.f}, {-3.f, -2.f}, {-2.f, -2.f}, {-1.f, -2.f},
|
| 104 |
+
{ 0.f, -2.f}, { 1.f, -2.f}, { 2.f, -2.f}, { 3.f, -2.f}, { 4.f, -2.f}, { 5.f, -2.f}, { 6.f, -2.f}, { 7.f, -2.f},
|
| 105 |
+
{-8.f, -1.f}, {-7.f, -1.f}, {-6.f, -1.f}, {-5.f, -1.f}, {-4.f, -1.f}, {-3.f, -1.f}, {-2.f, -1.f}, {-1.f, -1.f},
|
| 106 |
+
{ 0.f, -1.f}, { 1.f, -1.f}, { 2.f, -1.f}, { 3.f, -1.f}, { 4.f, -1.f}, { 5.f, -1.f}, { 6.f, -1.f}, { 7.f, -1.f},
|
| 107 |
+
{-8.f, 0.f}, {-7.f, 0.f}, {-6.f, 0.f}, {-5.f, 0.f}, {-4.f, 0.f}, {-3.f, 0.f}, {-2.f, 0.f}, {-1.f, 0.f},
|
| 108 |
+
{ 0.f, 0.f}, { 1.f, 0.f}, { 2.f, 0.f}, { 3.f, 0.f}, { 4.f, 0.f}, { 5.f, 0.f}, { 6.f, 0.f}, { 7.f, 0.f},
|
| 109 |
+
{-8.f, 1.f}, {-7.f, 1.f}, {-6.f, 1.f}, {-5.f, 1.f}, {-4.f, 1.f}, {-3.f, 1.f}, {-2.f, 1.f}, {-1.f, 1.f},
|
| 110 |
+
{ 0.f, 1.f}, { 1.f, 1.f}, { 2.f, 1.f}, { 3.f, 1.f}, { 4.f, 1.f}, { 5.f, 1.f}, { 6.f, 1.f}, { 7.f, 1.f},
|
| 111 |
+
{-8.f, 2.f}, {-7.f, 2.f}, {-6.f, 2.f}, {-5.f, 2.f}, {-4.f, 2.f}, {-3.f, 2.f}, {-2.f, 2.f}, {-1.f, 2.f},
|
| 112 |
+
{ 0.f, 2.f}, { 1.f, 2.f}, { 2.f, 2.f}, { 3.f, 2.f}, { 4.f, 2.f}, { 5.f, 2.f}, { 6.f, 2.f}, { 7.f, 2.f},
|
| 113 |
+
{-8.f, 3.f}, {-7.f, 3.f}, {-6.f, 3.f}, {-5.f, 3.f}, {-4.f, 3.f}, {-3.f, 3.f}, {-2.f, 3.f}, {-1.f, 3.f},
|
| 114 |
+
{ 0.f, 3.f}, { 1.f, 3.f}, { 2.f, 3.f}, { 3.f, 3.f}, { 4.f, 3.f}, { 5.f, 3.f}, { 6.f, 3.f}, { 7.f, 3.f},
|
| 115 |
+
{-8.f, 4.f}, {-7.f, 4.f}, {-6.f, 4.f}, {-5.f, 4.f}, {-4.f, 4.f}, {-3.f, 4.f}, {-2.f, 4.f}, {-1.f, 4.f},
|
| 116 |
+
{ 0.f, 4.f}, { 1.f, 4.f}, { 2.f, 4.f}, { 3.f, 4.f}, { 4.f, 4.f}, { 5.f, 4.f}, { 6.f, 4.f}, { 7.f, 4.f},
|
| 117 |
+
{-8.f, 5.f}, {-7.f, 5.f}, {-6.f, 5.f}, {-5.f, 5.f}, {-4.f, 5.f}, {-3.f, 5.f}, {-2.f, 5.f}, {-1.f, 5.f},
|
| 118 |
+
{ 0.f, 5.f}, { 1.f, 5.f}, { 2.f, 5.f}, { 3.f, 5.f}, { 4.f, 5.f}, { 5.f, 5.f}, { 6.f, 5.f}, { 7.f, 5.f},
|
| 119 |
+
{-8.f, 6.f}, {-7.f, 6.f}, {-6.f, 6.f}, {-5.f, 6.f}, {-4.f, 6.f}, {-3.f, 6.f}, {-2.f, 6.f}, {-1.f, 6.f},
|
| 120 |
+
{ 0.f, 6.f}, { 1.f, 6.f}, { 2.f, 6.f}, { 3.f, 6.f}, { 4.f, 6.f}, { 5.f, 6.f}, { 6.f, 6.f}, { 7.f, 6.f},
|
| 121 |
+
{-8.f, 7.f}, {-7.f, 7.f}, {-6.f, 7.f}, {-5.f, 7.f}, {-4.f, 7.f}, {-3.f, 7.f}, {-2.f, 7.f}, {-1.f, 7.f},
|
| 122 |
+
{ 0.f, 7.f}, { 1.f, 7.f}, { 2.f, 7.f}, { 3.f, 7.f}, { 4.f, 7.f}, { 5.f, 7.f}, { 6.f, 7.f}, { 7.f, 7.f}
|
| 123 |
+
};
|
| 124 |
+
double sum = 0;
|
| 125 |
+
for (int i=0; i<n; ++i) {
|
| 126 |
+
float d = x->d;
|
| 127 |
+
auto q = x->qs;
|
| 128 |
+
float s = 0;
|
| 129 |
+
for (int k=0; k<4; ++k) {
|
| 130 |
+
s += y[0]*kValues[q[0]].first + y[1]*kValues[q[0]].second +
|
| 131 |
+
y[2]*kValues[q[1]].first + y[3]*kValues[q[1]].second +
|
| 132 |
+
y[4]*kValues[q[2]].first + y[5]*kValues[q[2]].second +
|
| 133 |
+
y[6]*kValues[q[3]].first + y[7]*kValues[q[3]].second;
|
| 134 |
+
y += 8; q += 4;
|
| 135 |
+
}
|
| 136 |
+
sum += s*d;
|
| 137 |
+
++x;
|
| 138 |
+
}
|
| 139 |
+
return sum;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
inline double dot41(int n, const block_q4_1* x, const float* y) {
|
| 143 |
+
const static float kValues[16] = {0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f, 13.f, 14.f, 15.f};
|
| 144 |
+
constexpr uint32_t kMask1 = 0x0f0f0f0f;
|
| 145 |
+
uint32_t u1, u2;
|
| 146 |
+
auto q1 = (const uint8_t*)&u1;
|
| 147 |
+
auto q2 = (const uint8_t*)&u2;
|
| 148 |
+
double sum = 0;
|
| 149 |
+
for (int i=0; i<n; ++i) {
|
| 150 |
+
auto u = (const uint32_t*)x->qs;
|
| 151 |
+
float s = 0, s1 = 0;
|
| 152 |
+
for (int k=0; k<4; ++k) {
|
| 153 |
+
u1 = u[k] & kMask1;
|
| 154 |
+
u2 = (u[k] >> 4) & kMask1;
|
| 155 |
+
s += y[0]*kValues[q1[0]] + y[1]*kValues[q2[0]] +
|
| 156 |
+
y[2]*kValues[q1[1]] + y[3]*kValues[q2[1]] +
|
| 157 |
+
y[4]*kValues[q1[2]] + y[5]*kValues[q2[2]] +
|
| 158 |
+
y[6]*kValues[q1[3]] + y[7]*kValues[q2[3]];
|
| 159 |
+
s1 += y[0] + y[1] + y[2] + y[3] + y[4] + y[5] + y[6] + y[7];
|
| 160 |
+
y += 8;
|
| 161 |
+
}
|
| 162 |
+
sum += s*x->d + s1*x->m;
|
| 163 |
+
++x;
|
| 164 |
+
}
|
| 165 |
+
return sum;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
// Copy-pasted from ggml.c
|
| 169 |
+
static void quantize_row_q8_0_reference(const float *x, block_q8_0 *y, int k) {
|
| 170 |
+
assert(k % QK8_0 == 0);
|
| 171 |
+
const int nb = k / QK8_0;
|
| 172 |
+
|
| 173 |
+
for (int i = 0; i < nb; i++) {
|
| 174 |
+
float amax = 0.0f; // absolute max
|
| 175 |
+
|
| 176 |
+
for (int l = 0; l < QK8_0; l++) {
|
| 177 |
+
const float v = x[i*QK8_0 + l];
|
| 178 |
+
amax = std::max(amax, fabsf(v));
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
const float d = amax / ((1 << 7) - 1);
|
| 182 |
+
const float id = d ? 1.0f/d : 0.0f;
|
| 183 |
+
|
| 184 |
+
y[i].d = d;
|
| 185 |
+
|
| 186 |
+
for (int l = 0; l < QK8_0; ++l) {
|
| 187 |
+
const float v = x[i*QK8_0 + l]*id;
|
| 188 |
+
y[i].qs[l] = roundf(v);
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
// Copy-pasted from ggml.c
|
| 194 |
+
static void dot_q4_q8(const int n, float* s, const void* vx, const void* vy) {
|
| 195 |
+
const int nb = n / QK8_0;
|
| 196 |
+
const block_q4_0* x = (const block_q4_0*)vx;
|
| 197 |
+
const block_q8_0* y = (const block_q8_0*)vy;
|
| 198 |
+
float sumf = 0;
|
| 199 |
+
for (int i = 0; i < nb; i++) {
|
| 200 |
+
const float d0 = x[i].d;
|
| 201 |
+
const float d1 = y[i].d;
|
| 202 |
+
|
| 203 |
+
const uint8_t * p0 = x[i].qs;
|
| 204 |
+
const int8_t * p1 = y[i].qs;
|
| 205 |
+
|
| 206 |
+
int sumi = 0;
|
| 207 |
+
for (int j = 0; j < QK8_0/2; j++) {
|
| 208 |
+
const uint8_t v0 = p0[j];
|
| 209 |
+
|
| 210 |
+
const int i0 = (int8_t) (v0 & 0xf) - 8;
|
| 211 |
+
const int i1 = (int8_t) (v0 >> 4) - 8;
|
| 212 |
+
|
| 213 |
+
const int i2 = p1[2*j + 0];
|
| 214 |
+
const int i3 = p1[2*j + 1];
|
| 215 |
+
|
| 216 |
+
sumi += i0*i2 + i1*i3;
|
| 217 |
+
}
|
| 218 |
+
sumf += d0*d1*sumi;
|
| 219 |
+
}
|
| 220 |
+
*s = sumf;
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
int main(int argc, char** argv) {
|
| 224 |
+
|
| 225 |
+
int nloop = argc > 1 ? atoi(argv[1]) : 10;
|
| 226 |
+
bool scalar = argc > 2 ? atoi(argv[2]) : false;
|
| 227 |
+
bool useQ4_1 = argc > 3 ? atoi(argv[3]) : false;
|
| 228 |
+
|
| 229 |
+
if (scalar && useQ4_1) {
|
| 230 |
+
printf("It is not possible to use Q4_1 quantization and scalar implementations\n");
|
| 231 |
+
return 1;
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
std::mt19937 rndm(1234);
|
| 235 |
+
|
| 236 |
+
std::vector<float> x1(kVecSize), y1(kVecSize);
|
| 237 |
+
int n4 = useQ4_1 ? kVecSize / QK4_1 : kVecSize / QK4_0; n4 = 64*((n4 + 63)/64);
|
| 238 |
+
int n8 = kVecSize / QK8_0; n8 = 64*((n8 + 63)/64);
|
| 239 |
+
|
| 240 |
+
const auto * funcs_cpu = ggml_get_type_traits_cpu(useQ4_1 ? GGML_TYPE_Q4_1 : GGML_TYPE_Q4_0);
|
| 241 |
+
|
| 242 |
+
std::vector<block_q4_0> q40;
|
| 243 |
+
std::vector<block_q4_1> q41;
|
| 244 |
+
if (useQ4_1) q41.resize(n4);
|
| 245 |
+
else q40.resize(n4);
|
| 246 |
+
std::vector<block_q8_0> q8(n8);
|
| 247 |
+
double sumt = 0, sumt2 = 0, maxt = 0;
|
| 248 |
+
double sumqt = 0, sumqt2 = 0, maxqt = 0;
|
| 249 |
+
double sum = 0, sumq = 0, exactSum = 0;
|
| 250 |
+
for (int iloop=0; iloop<nloop; ++iloop) {
|
| 251 |
+
|
| 252 |
+
// Fill vector x with random numbers
|
| 253 |
+
fillRandomGaussianFloats(x1, rndm);
|
| 254 |
+
|
| 255 |
+
// Fill vector y with random numbers
|
| 256 |
+
fillRandomGaussianFloats(y1, rndm);
|
| 257 |
+
|
| 258 |
+
// Compute the exact dot product
|
| 259 |
+
for (int k=0; k<kVecSize; ++k) exactSum += x1[k]*y1[k];
|
| 260 |
+
|
| 261 |
+
// quantize x.
|
| 262 |
+
// Note, we do not include this in the timing as in practical application
|
| 263 |
+
// we already have the quantized model weights.
|
| 264 |
+
if (useQ4_1) {
|
| 265 |
+
funcs_cpu->from_float(x1.data(), q41.data(), kVecSize);
|
| 266 |
+
} else {
|
| 267 |
+
funcs_cpu->from_float(x1.data(), q40.data(), kVecSize);
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
// Now measure time the dot product needs using the "scalar" version above
|
| 271 |
+
auto t1 = std::chrono::high_resolution_clock::now();
|
| 272 |
+
if (useQ4_1) sum += dot41(kVecSize / QK4_1, q41.data(), y1.data());
|
| 273 |
+
else sum += dot(kVecSize / QK4_0, q40.data(), y1.data());
|
| 274 |
+
auto t2 = std::chrono::high_resolution_clock::now();
|
| 275 |
+
auto t = 1e-3*std::chrono::duration_cast<std::chrono::nanoseconds>(t2-t1).count();
|
| 276 |
+
sumt += t; sumt2 += t*t; maxt = std::max(maxt, t);
|
| 277 |
+
|
| 278 |
+
// And now measure the time needed to quantize y and perform the dot product with the quantized y
|
| 279 |
+
t1 = std::chrono::high_resolution_clock::now();
|
| 280 |
+
float result;
|
| 281 |
+
if (scalar) {
|
| 282 |
+
quantize_row_q8_0_reference(y1.data(), q8.data(), kVecSize);
|
| 283 |
+
dot_q4_q8(kVecSize, &result, q40.data(), q8.data());
|
| 284 |
+
}
|
| 285 |
+
else {
|
| 286 |
+
const auto * vdot = ggml_get_type_traits_cpu(funcs_cpu->vec_dot_type);
|
| 287 |
+
vdot->from_float(y1.data(), q8.data(), kVecSize);
|
| 288 |
+
if (useQ4_1) funcs_cpu->vec_dot(kVecSize, &result, 0, q41.data(), 0, q8.data(), 0, 1);
|
| 289 |
+
else funcs_cpu->vec_dot(kVecSize, &result, 0, q40.data(), 0, q8.data(), 0, 1);
|
| 290 |
+
}
|
| 291 |
+
sumq += result;
|
| 292 |
+
t2 = std::chrono::high_resolution_clock::now();
|
| 293 |
+
t = 1e-3*std::chrono::duration_cast<std::chrono::nanoseconds>(t2-t1).count();
|
| 294 |
+
sumqt += t; sumqt2 += t*t; maxqt = std::max(maxqt, t);
|
| 295 |
+
|
| 296 |
+
}
|
| 297 |
+
|
| 298 |
+
// Report the time (and the average of the dot products so the compiler does not come up with the idea
|
| 299 |
+
// of optimizing away the function calls after figuring that the result is not used).
|
| 300 |
+
sum /= nloop; sumq /= nloop;
|
| 301 |
+
exactSum /= nloop;
|
| 302 |
+
printf("Exact result: <dot> = %g\n",exactSum);
|
| 303 |
+
printf("<dot> = %g, %g\n",sum,sumq);
|
| 304 |
+
sumt /= nloop; sumt2 /= nloop; sumt2 -= sumt*sumt;
|
| 305 |
+
if (sumt2 > 0) sumt2 = sqrt(sumt2);
|
| 306 |
+
printf("time = %g +/- %g us. maxt = %g us\n",sumt,sumt2,maxt);
|
| 307 |
+
sumqt /= nloop; sumqt2 /= nloop; sumqt2 -= sumqt*sumqt;
|
| 308 |
+
if (sumqt2 > 0) sumqt2 = sqrt(sumqt2);
|
| 309 |
+
printf("timeq = %g +/- %g us. maxt = %g us\n",sumqt,sumqt2,maxqt);
|
| 310 |
+
return 0;
|
| 311 |
+
}
|
llama.cpp/scripts/apple/validate-apps.sh
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
./scripts/apple/validate-ios.sh
|
| 3 |
+
./scripts/apple/validate-macos.sh
|
| 4 |
+
./scripts/apple/validate-visionos.sh
|
| 5 |
+
./scripts/apple/validate-tvos.sh
|
llama.cpp/scripts/apple/validate-ios.sh
ADDED
|
@@ -0,0 +1,820 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
# validate-ios.sh - Validate iOS Application with embedded llama.xcframework using SwiftUI
|
| 3 |
+
|
| 4 |
+
# Authentication options (optional) (can be set via environment variables)
|
| 5 |
+
# To use: export APPLE_ID=your.email@example.com
|
| 6 |
+
# export APPLE_PASSWORD=your-app-specific-password
|
| 7 |
+
# ./validate-ios.sh
|
| 8 |
+
APPLE_ID=${APPLE_ID:-""}
|
| 9 |
+
APPLE_PASSWORD=${APPLE_PASSWORD:-""}
|
| 10 |
+
|
| 11 |
+
# Ensure the script exits on error
|
| 12 |
+
set -e
|
| 13 |
+
|
| 14 |
+
# Function to print usage instructions
|
| 15 |
+
print_usage() {
|
| 16 |
+
echo "Usage: ./validate-ios.sh [OPTIONS]"
|
| 17 |
+
echo ""
|
| 18 |
+
echo "Options:"
|
| 19 |
+
echo " --help Show this help message"
|
| 20 |
+
echo " --apple-id EMAIL Apple ID email for validation"
|
| 21 |
+
echo " --apple-password PWD App-specific password for Apple ID"
|
| 22 |
+
echo ""
|
| 23 |
+
echo "Environment variables:"
|
| 24 |
+
echo " APPLE_ID Apple ID email for validation"
|
| 25 |
+
echo " APPLE_PASSWORD App-specific password for Apple ID"
|
| 26 |
+
echo ""
|
| 27 |
+
echo "Notes:"
|
| 28 |
+
echo " - Command line options take precedence over environment variables"
|
| 29 |
+
echo " - Authentication is optional. If not provided, alternative validation will be performed"
|
| 30 |
+
echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
# Parse command line arguments
|
| 34 |
+
while [[ $# -gt 0 ]]; do
|
| 35 |
+
case $1 in
|
| 36 |
+
--help)
|
| 37 |
+
print_usage
|
| 38 |
+
exit 0
|
| 39 |
+
;;
|
| 40 |
+
--apple-id)
|
| 41 |
+
APPLE_ID="$2"
|
| 42 |
+
shift 2
|
| 43 |
+
;;
|
| 44 |
+
--apple-password)
|
| 45 |
+
APPLE_PASSWORD="$2"
|
| 46 |
+
shift 2
|
| 47 |
+
;;
|
| 48 |
+
*)
|
| 49 |
+
echo "Unknown option: $1"
|
| 50 |
+
print_usage
|
| 51 |
+
exit 1
|
| 52 |
+
;;
|
| 53 |
+
esac
|
| 54 |
+
done
|
| 55 |
+
|
| 56 |
+
# Function to clean up in case of error
|
| 57 |
+
cleanup() {
|
| 58 |
+
# Don't clean up temp files on error to help with debugging
|
| 59 |
+
echo "===== iOS Validation Process Failed ====="
|
| 60 |
+
exit 1
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
# Set up trap to call cleanup function on error
|
| 64 |
+
trap cleanup ERR
|
| 65 |
+
|
| 66 |
+
set -e # Exit on any error
|
| 67 |
+
|
| 68 |
+
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
|
| 69 |
+
BUILD_DIR="${ROOT_DIR}/validation-builds/ios"
|
| 70 |
+
|
| 71 |
+
# Configuration
|
| 72 |
+
APP_NAME="iOSLlamaTest"
|
| 73 |
+
BUNDLE_ID="org.ggml.iOSLlamaTest"
|
| 74 |
+
XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/llama.xcframework"
|
| 75 |
+
TEMP_DIR="${BUILD_DIR}/temp"
|
| 76 |
+
ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
|
| 77 |
+
IPA_PATH="${BUILD_DIR}/${APP_NAME}.ipa"
|
| 78 |
+
VALIDATION_DIR="${BUILD_DIR}/validation"
|
| 79 |
+
|
| 80 |
+
# Create necessary directories
|
| 81 |
+
mkdir -p "${BUILD_DIR}"
|
| 82 |
+
mkdir -p "${TEMP_DIR}"
|
| 83 |
+
mkdir -p "${VALIDATION_DIR}"
|
| 84 |
+
|
| 85 |
+
echo "===== iOS Validation Process Started ====="
|
| 86 |
+
|
| 87 |
+
# 1. Create a simple test app project
|
| 88 |
+
echo "Creating test iOS app project..."
|
| 89 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
|
| 90 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
|
| 91 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 92 |
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
| 93 |
+
<plist version="1.0">
|
| 94 |
+
<dict>
|
| 95 |
+
<key>CFBundleDevelopmentRegion</key>
|
| 96 |
+
<string>en</string>
|
| 97 |
+
<key>CFBundleExecutable</key>
|
| 98 |
+
<string>${APP_NAME}</string>
|
| 99 |
+
<key>CFBundleIdentifier</key>
|
| 100 |
+
<string>${BUNDLE_ID}</string>
|
| 101 |
+
<key>CFBundleInfoDictionaryVersion</key>
|
| 102 |
+
<string>6.0</string>
|
| 103 |
+
<key>CFBundleName</key>
|
| 104 |
+
<string>${APP_NAME}</string>
|
| 105 |
+
<key>CFBundlePackageType</key>
|
| 106 |
+
<string>APPL</string>
|
| 107 |
+
<key>CFBundleShortVersionString</key>
|
| 108 |
+
<string>1.0</string>
|
| 109 |
+
<key>CFBundleVersion</key>
|
| 110 |
+
<string>1</string>
|
| 111 |
+
<key>LSRequiresIPhoneOS</key>
|
| 112 |
+
<true/>
|
| 113 |
+
<key>UILaunchScreen</key>
|
| 114 |
+
<dict/>
|
| 115 |
+
<key>UIRequiredDeviceCapabilities</key>
|
| 116 |
+
<array>
|
| 117 |
+
<string>armv7</string>
|
| 118 |
+
</array>
|
| 119 |
+
<key>UISupportedInterfaceOrientations</key>
|
| 120 |
+
<array>
|
| 121 |
+
<string>UIInterfaceOrientationPortrait</string>
|
| 122 |
+
</array>
|
| 123 |
+
</dict>
|
| 124 |
+
</plist>
|
| 125 |
+
EOF
|
| 126 |
+
|
| 127 |
+
# Create SwiftUI app files
|
| 128 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
|
| 129 |
+
|
| 130 |
+
# Create App.swift
|
| 131 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
|
| 132 |
+
import SwiftUI
|
| 133 |
+
import llama
|
| 134 |
+
|
| 135 |
+
@main
|
| 136 |
+
struct LlamaTestApp: App {
|
| 137 |
+
var body: some Scene {
|
| 138 |
+
WindowGroup {
|
| 139 |
+
ContentView()
|
| 140 |
+
}
|
| 141 |
+
}
|
| 142 |
+
}
|
| 143 |
+
EOF
|
| 144 |
+
|
| 145 |
+
# Create ContentView.swift
|
| 146 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
|
| 147 |
+
import SwiftUI
|
| 148 |
+
import llama
|
| 149 |
+
|
| 150 |
+
struct ContentView: View {
|
| 151 |
+
// Test that we can initialize a llama context params struct
|
| 152 |
+
let params = llama_context_default_params()
|
| 153 |
+
|
| 154 |
+
var body: some View {
|
| 155 |
+
VStack(spacing: 20) {
|
| 156 |
+
Text("Llama Framework Test")
|
| 157 |
+
.font(.largeTitle)
|
| 158 |
+
.padding()
|
| 159 |
+
|
| 160 |
+
Text("llama_context_default_params() created successfully")
|
| 161 |
+
.font(.headline)
|
| 162 |
+
.multilineTextAlignment(.center)
|
| 163 |
+
.padding()
|
| 164 |
+
|
| 165 |
+
// Display some param values to confirm the framework is working
|
| 166 |
+
Text("n_ctx: \(params.n_ctx)")
|
| 167 |
+
.font(.body)
|
| 168 |
+
|
| 169 |
+
Text("n_batch: \(params.n_batch)")
|
| 170 |
+
.font(.body)
|
| 171 |
+
|
| 172 |
+
Spacer()
|
| 173 |
+
}
|
| 174 |
+
.padding()
|
| 175 |
+
}
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
struct ContentView_Previews: PreviewProvider {
|
| 179 |
+
static var previews: some View {
|
| 180 |
+
ContentView()
|
| 181 |
+
}
|
| 182 |
+
}
|
| 183 |
+
EOF
|
| 184 |
+
|
| 185 |
+
# Create project.pbxproj, fixing the framework search paths issues
|
| 186 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
|
| 187 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 188 |
+
// !$*UTF8*$!
|
| 189 |
+
{
|
| 190 |
+
archiveVersion = 1;
|
| 191 |
+
classes = {
|
| 192 |
+
};
|
| 193 |
+
objectVersion = 54;
|
| 194 |
+
objects = {
|
| 195 |
+
|
| 196 |
+
/* Begin PBXBuildFile section */
|
| 197 |
+
11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
|
| 198 |
+
33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
|
| 199 |
+
55555555555555555555555 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 200 |
+
77777777777777777777777 /* llama.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 201 |
+
/* End PBXBuildFile section */
|
| 202 |
+
|
| 203 |
+
/* Begin PBXCopyFilesBuildPhase section */
|
| 204 |
+
88888888888888888888888 /* Embed Frameworks */ = {
|
| 205 |
+
isa = PBXCopyFilesBuildPhase;
|
| 206 |
+
buildActionMask = 2147483647;
|
| 207 |
+
dstPath = "";
|
| 208 |
+
dstSubfolderSpec = 10;
|
| 209 |
+
files = (
|
| 210 |
+
77777777777777777777777 /* llama.xcframework in Embed Frameworks */,
|
| 211 |
+
);
|
| 212 |
+
name = "Embed Frameworks";
|
| 213 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 214 |
+
};
|
| 215 |
+
/* End PBXCopyFilesBuildPhase section */
|
| 216 |
+
|
| 217 |
+
/* Begin PBXFileReference section */
|
| 218 |
+
EOF
|
| 219 |
+
|
| 220 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 221 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 222 |
+
99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 223 |
+
22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
|
| 224 |
+
44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
| 225 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
| 226 |
+
66666666666666666666666 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; };
|
| 227 |
+
/* End PBXFileReference section */
|
| 228 |
+
EOF
|
| 229 |
+
|
| 230 |
+
# Add the rest of the project file with fixed framework search paths
|
| 231 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 232 |
+
/* Begin PBXFrameworksBuildPhase section */
|
| 233 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
|
| 234 |
+
isa = PBXFrameworksBuildPhase;
|
| 235 |
+
buildActionMask = 2147483647;
|
| 236 |
+
files = (
|
| 237 |
+
55555555555555555555555 /* llama.xcframework in Frameworks */,
|
| 238 |
+
);
|
| 239 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 240 |
+
};
|
| 241 |
+
/* End PBXFrameworksBuildPhase section */
|
| 242 |
+
|
| 243 |
+
/* Begin PBXGroup section */
|
| 244 |
+
EOF
|
| 245 |
+
|
| 246 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 247 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 248 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
|
| 249 |
+
isa = PBXGroup;
|
| 250 |
+
children = (
|
| 251 |
+
99999999999999999999999 /* ${APP_NAME}.app */,
|
| 252 |
+
);
|
| 253 |
+
name = Products;
|
| 254 |
+
sourceTree = "<group>";
|
| 255 |
+
};
|
| 256 |
+
EOF
|
| 257 |
+
|
| 258 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 259 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
|
| 260 |
+
isa = PBXGroup;
|
| 261 |
+
children = (
|
| 262 |
+
66666666666666666666666 /* llama.xcframework */,
|
| 263 |
+
);
|
| 264 |
+
name = Frameworks;
|
| 265 |
+
sourceTree = "<group>";
|
| 266 |
+
};
|
| 267 |
+
EEEEEEEEEEEEEEEEEEEEEEEE = {
|
| 268 |
+
isa = PBXGroup;
|
| 269 |
+
children = (
|
| 270 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* iOSLlamaTest */,
|
| 271 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
|
| 272 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
|
| 273 |
+
);
|
| 274 |
+
sourceTree = "<group>";
|
| 275 |
+
};
|
| 276 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* iOSLlamaTest */ = {
|
| 277 |
+
isa = PBXGroup;
|
| 278 |
+
children = (
|
| 279 |
+
1111111111111111111111AA /* Sources */,
|
| 280 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
|
| 281 |
+
);
|
| 282 |
+
path = "iOSLlamaTest";
|
| 283 |
+
sourceTree = "<group>";
|
| 284 |
+
};
|
| 285 |
+
1111111111111111111111AA /* Sources */ = {
|
| 286 |
+
isa = PBXGroup;
|
| 287 |
+
children = (
|
| 288 |
+
22222222222222222222222 /* App.swift */,
|
| 289 |
+
44444444444444444444444 /* ContentView.swift */,
|
| 290 |
+
);
|
| 291 |
+
path = Sources;
|
| 292 |
+
sourceTree = "<group>";
|
| 293 |
+
};
|
| 294 |
+
/* End PBXGroup section */
|
| 295 |
+
EOF
|
| 296 |
+
|
| 297 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 298 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 299 |
+
/* Begin PBXNativeTarget section */
|
| 300 |
+
3333333333333333333333AA /* ${APP_NAME} */ = {
|
| 301 |
+
isa = PBXNativeTarget;
|
| 302 |
+
buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
|
| 303 |
+
buildPhases = (
|
| 304 |
+
5555555555555555555555AA /* Sources */,
|
| 305 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
|
| 306 |
+
6666666666666666666666AA /* Resources */,
|
| 307 |
+
88888888888888888888888 /* Embed Frameworks */,
|
| 308 |
+
);
|
| 309 |
+
buildRules = (
|
| 310 |
+
);
|
| 311 |
+
dependencies = (
|
| 312 |
+
);
|
| 313 |
+
name = "${APP_NAME}";
|
| 314 |
+
productName = "${APP_NAME}";
|
| 315 |
+
productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
|
| 316 |
+
productType = "com.apple.product-type.application";
|
| 317 |
+
};
|
| 318 |
+
/* End PBXNativeTarget section */
|
| 319 |
+
|
| 320 |
+
/* Begin PBXProject section */
|
| 321 |
+
7777777777777777777777AA /* Project object */ = {
|
| 322 |
+
isa = PBXProject;
|
| 323 |
+
attributes = {
|
| 324 |
+
LastSwiftUpdateCheck = 1240;
|
| 325 |
+
LastUpgradeCheck = 1240;
|
| 326 |
+
TargetAttributes = {
|
| 327 |
+
3333333333333333333333AA = {
|
| 328 |
+
CreatedOnToolsVersion = 12.4;
|
| 329 |
+
};
|
| 330 |
+
};
|
| 331 |
+
};
|
| 332 |
+
buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
|
| 333 |
+
compatibilityVersion = "Xcode 12.0";
|
| 334 |
+
developmentRegion = en;
|
| 335 |
+
hasScannedForEncodings = 0;
|
| 336 |
+
knownRegions = (
|
| 337 |
+
en,
|
| 338 |
+
Base,
|
| 339 |
+
);
|
| 340 |
+
mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
|
| 341 |
+
productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
|
| 342 |
+
projectDirPath = "";
|
| 343 |
+
projectRoot = "";
|
| 344 |
+
targets = (
|
| 345 |
+
3333333333333333333333AA /* ${APP_NAME} */,
|
| 346 |
+
);
|
| 347 |
+
};
|
| 348 |
+
/* End PBXProject section */
|
| 349 |
+
EOF
|
| 350 |
+
|
| 351 |
+
# Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS
|
| 352 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 353 |
+
/* Begin PBXResourcesBuildPhase section */
|
| 354 |
+
6666666666666666666666AA /* Resources */ = {
|
| 355 |
+
isa = PBXResourcesBuildPhase;
|
| 356 |
+
buildActionMask = 2147483647;
|
| 357 |
+
files = (
|
| 358 |
+
);
|
| 359 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 360 |
+
};
|
| 361 |
+
/* End PBXResourcesBuildPhase section */
|
| 362 |
+
|
| 363 |
+
/* Begin PBXSourcesBuildPhase section */
|
| 364 |
+
5555555555555555555555AA /* Sources */ = {
|
| 365 |
+
isa = PBXSourcesBuildPhase;
|
| 366 |
+
buildActionMask = 2147483647;
|
| 367 |
+
files = (
|
| 368 |
+
33333333333333333333333 /* ContentView.swift in Sources */,
|
| 369 |
+
11111111111111111111111 /* App.swift in Sources */,
|
| 370 |
+
);
|
| 371 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 372 |
+
};
|
| 373 |
+
/* End PBXSourcesBuildPhase section */
|
| 374 |
+
|
| 375 |
+
/* Begin XCBuildConfiguration section */
|
| 376 |
+
9999999999999999999999AA /* Debug */ = {
|
| 377 |
+
isa = XCBuildConfiguration;
|
| 378 |
+
buildSettings = {
|
| 379 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 380 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 381 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 382 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 383 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 384 |
+
CLANG_ENABLE_MODULES = YES;
|
| 385 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 386 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 387 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 388 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 389 |
+
CLANG_WARN_COMMA = YES;
|
| 390 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 391 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 392 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 393 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 394 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 395 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 396 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 397 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 398 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 399 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 400 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 401 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 402 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 403 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 404 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 405 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 406 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 407 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 408 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 409 |
+
COPY_PHASE_STRIP = NO;
|
| 410 |
+
DEBUG_INFORMATION_FORMAT = dwarf;
|
| 411 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 412 |
+
ENABLE_TESTABILITY = YES;
|
| 413 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 414 |
+
GCC_DYNAMIC_NO_PIC = NO;
|
| 415 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 416 |
+
GCC_OPTIMIZATION_LEVEL = 0;
|
| 417 |
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
| 418 |
+
"DEBUG=1",
|
| 419 |
+
"$(inherited)",
|
| 420 |
+
);
|
| 421 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 422 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 423 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 424 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 425 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 426 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 427 |
+
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
|
| 428 |
+
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
| 429 |
+
MTL_FAST_MATH = YES;
|
| 430 |
+
ONLY_ACTIVE_ARCH = YES;
|
| 431 |
+
SDKROOT = iphoneos;
|
| 432 |
+
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
| 433 |
+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
| 434 |
+
};
|
| 435 |
+
name = Debug;
|
| 436 |
+
};
|
| 437 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
|
| 438 |
+
isa = XCBuildConfiguration;
|
| 439 |
+
buildSettings = {
|
| 440 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 441 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 442 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 443 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 444 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 445 |
+
CLANG_ENABLE_MODULES = YES;
|
| 446 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 447 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 448 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 449 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 450 |
+
CLANG_WARN_COMMA = YES;
|
| 451 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 452 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 453 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 454 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 455 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 456 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 457 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 458 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 459 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 460 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 461 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 462 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 463 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 464 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 465 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 466 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 467 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 468 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 469 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 470 |
+
COPY_PHASE_STRIP = NO;
|
| 471 |
+
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
| 472 |
+
ENABLE_NS_ASSERTIONS = NO;
|
| 473 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 474 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 475 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 476 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 477 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 478 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 479 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 480 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 481 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 482 |
+
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
|
| 483 |
+
MTL_ENABLE_DEBUG_INFO = NO;
|
| 484 |
+
MTL_FAST_MATH = YES;
|
| 485 |
+
SDKROOT = iphoneos;
|
| 486 |
+
SWIFT_COMPILATION_MODE = wholemodule;
|
| 487 |
+
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
| 488 |
+
VALIDATE_PRODUCT = YES;
|
| 489 |
+
};
|
| 490 |
+
name = Release;
|
| 491 |
+
};
|
| 492 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
|
| 493 |
+
isa = XCBuildConfiguration;
|
| 494 |
+
buildSettings = {
|
| 495 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 496 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 497 |
+
CODE_SIGN_STYLE = Manual;
|
| 498 |
+
DEVELOPMENT_TEAM = "";
|
| 499 |
+
ENABLE_PREVIEWS = YES;
|
| 500 |
+
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
| 501 |
+
INFOPLIST_FILE = "iOSLlamaTest/Info.plist";
|
| 502 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 503 |
+
"$(inherited)",
|
| 504 |
+
"@executable_path/Frameworks",
|
| 505 |
+
);
|
| 506 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.iOSLlamaTest";
|
| 507 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 508 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 509 |
+
SWIFT_VERSION = 5.0;
|
| 510 |
+
TARGETED_DEVICE_FAMILY = "1,2";
|
| 511 |
+
};
|
| 512 |
+
name = Debug;
|
| 513 |
+
};
|
| 514 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
|
| 515 |
+
isa = XCBuildConfiguration;
|
| 516 |
+
buildSettings = {
|
| 517 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 518 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 519 |
+
CODE_SIGN_STYLE = Manual;
|
| 520 |
+
DEVELOPMENT_TEAM = "";
|
| 521 |
+
ENABLE_PREVIEWS = YES;
|
| 522 |
+
FRAMEWORK_SEARCH_PATHS = (
|
| 523 |
+
"$(inherited)",
|
| 524 |
+
"$(PROJECT_DIR)",
|
| 525 |
+
);
|
| 526 |
+
INFOPLIST_FILE = "iOSLlamaTest/Info.plist";
|
| 527 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 528 |
+
"$(inherited)",
|
| 529 |
+
"@executable_path/Frameworks",
|
| 530 |
+
);
|
| 531 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.iOSLlamaTest";
|
| 532 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 533 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 534 |
+
SWIFT_VERSION = 5.0;
|
| 535 |
+
TARGETED_DEVICE_FAMILY = "1,2";
|
| 536 |
+
};
|
| 537 |
+
name = Release;
|
| 538 |
+
};
|
| 539 |
+
/* End XCBuildConfiguration section */
|
| 540 |
+
EOF
|
| 541 |
+
|
| 542 |
+
# Finish the project.pbxproj file
|
| 543 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 544 |
+
/* Begin XCConfigurationList section */
|
| 545 |
+
8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
|
| 546 |
+
isa = XCConfigurationList;
|
| 547 |
+
buildConfigurations = (
|
| 548 |
+
9999999999999999999999AA /* Debug */,
|
| 549 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
|
| 550 |
+
);
|
| 551 |
+
defaultConfigurationIsVisible = 0;
|
| 552 |
+
defaultConfigurationName = Release;
|
| 553 |
+
};
|
| 554 |
+
4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
|
| 555 |
+
isa = XCConfigurationList;
|
| 556 |
+
buildConfigurations = (
|
| 557 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
|
| 558 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
|
| 559 |
+
);
|
| 560 |
+
defaultConfigurationIsVisible = 0;
|
| 561 |
+
defaultConfigurationName = Release;
|
| 562 |
+
};
|
| 563 |
+
/* End XCConfigurationList section */
|
| 564 |
+
};
|
| 565 |
+
rootObject = 7777777777777777777777AA /* Project object */;
|
| 566 |
+
}
|
| 567 |
+
EOF
|
| 568 |
+
|
| 569 |
+
# 2. Copy XCFramework to test project
|
| 570 |
+
echo "Copying XCFramework to test project..."
|
| 571 |
+
cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
|
| 572 |
+
|
| 573 |
+
# 3. Build and archive the app
|
| 574 |
+
echo "Building and archiving test app..."
|
| 575 |
+
cd "${TEMP_DIR}/${APP_NAME}"
|
| 576 |
+
|
| 577 |
+
# Create a simple xcscheme file to avoid xcodebuild scheme issues
|
| 578 |
+
mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
|
| 579 |
+
cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
|
| 580 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 581 |
+
<Scheme
|
| 582 |
+
LastUpgradeVersion = "1240"
|
| 583 |
+
version = "1.3">
|
| 584 |
+
<BuildAction
|
| 585 |
+
parallelizeBuildables = "YES"
|
| 586 |
+
buildImplicitDependencies = "YES">
|
| 587 |
+
<BuildActionEntries>
|
| 588 |
+
<BuildActionEntry
|
| 589 |
+
buildForTesting = "YES"
|
| 590 |
+
buildForRunning = "YES"
|
| 591 |
+
buildForProfiling = "YES"
|
| 592 |
+
buildForArchiving = "YES"
|
| 593 |
+
buildForAnalyzing = "YES">
|
| 594 |
+
<BuildableReference
|
| 595 |
+
BuildableIdentifier = "primary"
|
| 596 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 597 |
+
BuildableName = "${APP_NAME}.app"
|
| 598 |
+
BlueprintName = "${APP_NAME}"
|
| 599 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 600 |
+
</BuildableReference>
|
| 601 |
+
</BuildActionEntry>
|
| 602 |
+
</BuildActionEntries>
|
| 603 |
+
</BuildAction>
|
| 604 |
+
<TestAction
|
| 605 |
+
buildConfiguration = "Debug"
|
| 606 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 607 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 608 |
+
shouldUseLaunchSchemeArgsEnv = "YES">
|
| 609 |
+
<Testables>
|
| 610 |
+
</Testables>
|
| 611 |
+
</TestAction>
|
| 612 |
+
<LaunchAction
|
| 613 |
+
buildConfiguration = "Debug"
|
| 614 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 615 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 616 |
+
launchStyle = "0"
|
| 617 |
+
useCustomWorkingDirectory = "NO"
|
| 618 |
+
ignoresPersistentStateOnLaunch = "NO"
|
| 619 |
+
debugDocumentVersioning = "YES"
|
| 620 |
+
debugServiceExtension = "internal"
|
| 621 |
+
allowLocationSimulation = "YES">
|
| 622 |
+
<BuildableProductRunnable
|
| 623 |
+
runnableDebuggingMode = "0">
|
| 624 |
+
<BuildableReference
|
| 625 |
+
BuildableIdentifier = "primary"
|
| 626 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 627 |
+
BuildableName = "${APP_NAME}.app"
|
| 628 |
+
BlueprintName = "${APP_NAME}"
|
| 629 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 630 |
+
</BuildableReference>
|
| 631 |
+
</BuildableProductRunnable>
|
| 632 |
+
</LaunchAction>
|
| 633 |
+
<ProfileAction
|
| 634 |
+
buildConfiguration = "Release"
|
| 635 |
+
shouldUseLaunchSchemeArgsEnv = "YES"
|
| 636 |
+
savedToolIdentifier = ""
|
| 637 |
+
useCustomWorkingDirectory = "NO"
|
| 638 |
+
debugDocumentVersioning = "YES">
|
| 639 |
+
<BuildableProductRunnable
|
| 640 |
+
runnableDebuggingMode = "0">
|
| 641 |
+
<BuildableReference
|
| 642 |
+
BuildableIdentifier = "primary"
|
| 643 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 644 |
+
BuildableName = "${APP_NAME}.app"
|
| 645 |
+
BlueprintName = "${APP_NAME}"
|
| 646 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 647 |
+
</BuildableReference>
|
| 648 |
+
</BuildableProductRunnable>
|
| 649 |
+
</ProfileAction>
|
| 650 |
+
<AnalyzeAction
|
| 651 |
+
buildConfiguration = "Debug">
|
| 652 |
+
</AnalyzeAction>
|
| 653 |
+
<ArchiveAction
|
| 654 |
+
buildConfiguration = "Release"
|
| 655 |
+
revealArchiveInOrganizer = "YES">
|
| 656 |
+
</ArchiveAction>
|
| 657 |
+
</Scheme>
|
| 658 |
+
EOF
|
| 659 |
+
|
| 660 |
+
# Now use xcodebuild with an explicitly defined product name
|
| 661 |
+
xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk iphoneos -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
|
| 662 |
+
|
| 663 |
+
# 4. Create IPA from archive
|
| 664 |
+
echo "Creating IPA from archive..."
|
| 665 |
+
mkdir -p "${TEMP_DIR}/Payload"
|
| 666 |
+
cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${TEMP_DIR}/Payload/"
|
| 667 |
+
|
| 668 |
+
# Check and log app structure before zipping
|
| 669 |
+
echo "App structure:"
|
| 670 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/"
|
| 671 |
+
echo "Frameworks:"
|
| 672 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 673 |
+
|
| 674 |
+
cd "${TEMP_DIR}"
|
| 675 |
+
zip -r "${IPA_PATH}" Payload
|
| 676 |
+
|
| 677 |
+
# Check embedded provisioning profile
|
| 678 |
+
echo "Checking provisioning profile (if any)..."
|
| 679 |
+
PROVISIONING_PROFILE=$(find "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" -name "embedded.mobileprovision" 2>/dev/null)
|
| 680 |
+
if [ -n "$PROVISIONING_PROFILE" ]; then
|
| 681 |
+
echo "Found embedded provisioning profile:"
|
| 682 |
+
security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
|
| 683 |
+
else
|
| 684 |
+
echo "No embedded provisioning profile found (expected for ad-hoc builds)"
|
| 685 |
+
fi
|
| 686 |
+
|
| 687 |
+
# 5. Validate the IPA
|
| 688 |
+
echo "Validating IPA..."
|
| 689 |
+
VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
|
| 690 |
+
|
| 691 |
+
# Check if authentication credentials are provided
|
| 692 |
+
AUTH_ARGS=""
|
| 693 |
+
if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
|
| 694 |
+
echo "Using Apple ID authentication for validation..."
|
| 695 |
+
AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
|
| 696 |
+
else
|
| 697 |
+
echo "No authentication credentials provided. Will perform basic validation."
|
| 698 |
+
echo "To use your personal developer account, you can run the script with:"
|
| 699 |
+
echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-ios.sh"
|
| 700 |
+
echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
|
| 701 |
+
fi
|
| 702 |
+
|
| 703 |
+
# Run validation with detailed output
|
| 704 |
+
echo "Running validation with altool..."
|
| 705 |
+
if [ -n "$AUTH_ARGS" ]; then
|
| 706 |
+
# Use eval to properly handle the quoted arguments
|
| 707 |
+
eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type ios --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 708 |
+
else
|
| 709 |
+
xcrun altool --validate-app -f "${IPA_PATH}" --type ios --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 710 |
+
fi
|
| 711 |
+
VALIDATION_RESULT=$?
|
| 712 |
+
|
| 713 |
+
# Final validation result
|
| 714 |
+
FINAL_VALIDATION_RESULT=0
|
| 715 |
+
|
| 716 |
+
# Check if validation failed because the app isn't in App Store Connect
|
| 717 |
+
if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then
|
| 718 |
+
echo "⚠️ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"
|
| 719 |
+
echo "This is expected for apps that haven't been registered in App Store Connect yet."
|
| 720 |
+
echo "This doesn't indicate a problem with the build or framework."
|
| 721 |
+
|
| 722 |
+
# Perform alternative validation
|
| 723 |
+
echo "Performing alternative validation checks..."
|
| 724 |
+
|
| 725 |
+
# Check if IPA was created successfully
|
| 726 |
+
if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then
|
| 727 |
+
echo "✅ IPA file created successfully"
|
| 728 |
+
else
|
| 729 |
+
echo "❌ IPA file not created or empty"
|
| 730 |
+
FINAL_VALIDATION_RESULT=1
|
| 731 |
+
fi
|
| 732 |
+
|
| 733 |
+
# Check if app binary exists and is executable
|
| 734 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then
|
| 735 |
+
echo "✅ App binary exists and is executable"
|
| 736 |
+
else
|
| 737 |
+
echo "❌ App binary missing or not executable"
|
| 738 |
+
FINAL_VALIDATION_RESULT=1
|
| 739 |
+
fi
|
| 740 |
+
|
| 741 |
+
# Check if framework was properly embedded
|
| 742 |
+
if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework" ]; then
|
| 743 |
+
echo "✅ llama.framework properly embedded"
|
| 744 |
+
else
|
| 745 |
+
echo "❌ llama.framework not properly embedded"
|
| 746 |
+
FINAL_VALIDATION_RESULT=1
|
| 747 |
+
fi
|
| 748 |
+
|
| 749 |
+
# Check if framework binary exists
|
| 750 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" ]; then
|
| 751 |
+
echo "✅ Framework binary exists"
|
| 752 |
+
|
| 753 |
+
# Further validate framework by checking architecture
|
| 754 |
+
ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" 2>/dev/null | grep -o "arm64\\|armv7\\|x86_64" | tr '\n' ' ')
|
| 755 |
+
if [ -n "$ARCHS" ]; then
|
| 756 |
+
echo "✅ Framework architecture(s): $ARCHS"
|
| 757 |
+
else
|
| 758 |
+
echo "⚠️ Could not determine framework architecture"
|
| 759 |
+
fi
|
| 760 |
+
else
|
| 761 |
+
echo "❌ Framework binary missing"
|
| 762 |
+
FINAL_VALIDATION_RESULT=1
|
| 763 |
+
fi
|
| 764 |
+
|
| 765 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 766 |
+
echo "✅ Alternative validation PASSED: App built successfully with embedded framework"
|
| 767 |
+
else
|
| 768 |
+
echo "❌ Alternative validation FAILED: Issues found with the app or framework"
|
| 769 |
+
fi
|
| 770 |
+
elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then
|
| 771 |
+
echo "✅ iOS Validation PASSED: IPA successfully validated"
|
| 772 |
+
echo "Results saved to ${VALIDATION_OUTPUT}"
|
| 773 |
+
else
|
| 774 |
+
echo "❌ iOS Validation FAILED: IPA validation found issues"
|
| 775 |
+
echo "See validation output at ${VALIDATION_OUTPUT}"
|
| 776 |
+
echo ""
|
| 777 |
+
echo "==== VALIDATION ERRORS ===="
|
| 778 |
+
|
| 779 |
+
# Try to extract specific errors from the output
|
| 780 |
+
if grep -q "Error" "${VALIDATION_OUTPUT}"; then
|
| 781 |
+
grep -A 5 "Error" "${VALIDATION_OUTPUT}"
|
| 782 |
+
else
|
| 783 |
+
# If no specific error found, show the whole log
|
| 784 |
+
cat "${VALIDATION_OUTPUT}"
|
| 785 |
+
fi
|
| 786 |
+
|
| 787 |
+
# Additional debugging: check IPA contents
|
| 788 |
+
echo ""
|
| 789 |
+
echo "==== IPA CONTENTS ===="
|
| 790 |
+
mkdir -p "${TEMP_DIR}/ipa_contents"
|
| 791 |
+
unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"
|
| 792 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"
|
| 793 |
+
|
| 794 |
+
# Check for code signing issues
|
| 795 |
+
echo ""
|
| 796 |
+
echo "==== CODE SIGNING INFO ===="
|
| 797 |
+
codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"
|
| 798 |
+
|
| 799 |
+
# Check embedded frameworks
|
| 800 |
+
echo ""
|
| 801 |
+
echo "==== FRAMEWORK INFO ===="
|
| 802 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 803 |
+
fi
|
| 804 |
+
|
| 805 |
+
# Don't clean up on error to allow inspection
|
| 806 |
+
if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
|
| 807 |
+
echo ""
|
| 808 |
+
echo "Temporary files kept for inspection at: ${TEMP_DIR}"
|
| 809 |
+
echo "===== iOS Validation Process Failed ====="
|
| 810 |
+
exit 1
|
| 811 |
+
fi
|
| 812 |
+
|
| 813 |
+
# Clean up temporary files but keep build artifacts
|
| 814 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 815 |
+
echo "Cleaning up temporary files..."
|
| 816 |
+
#rm -rf "${TEMP_DIR}"
|
| 817 |
+
fi
|
| 818 |
+
|
| 819 |
+
echo "===== iOS Validation Process Completed ====="
|
| 820 |
+
exit $FINAL_VALIDATION_RESULT
|
llama.cpp/scripts/apple/validate-macos.sh
ADDED
|
@@ -0,0 +1,781 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
# validate-macos.sh - Validate macOS Application with embedded llama.xcframework using SwiftUI
|
| 3 |
+
|
| 4 |
+
# Authentication options (optional) (can be set via environment variables)
|
| 5 |
+
# To use: export APPLE_ID=your.email@example.com
|
| 6 |
+
# export APPLE_PASSWORD=your-app-specific-password
|
| 7 |
+
# ./validate-macos.sh
|
| 8 |
+
APPLE_ID=${APPLE_ID:-""}
|
| 9 |
+
APPLE_PASSWORD=${APPLE_PASSWORD:-""}
|
| 10 |
+
|
| 11 |
+
# Ensure the script exits on error
|
| 12 |
+
set -e
|
| 13 |
+
|
| 14 |
+
# Function to print usage instructions
|
| 15 |
+
print_usage() {
|
| 16 |
+
echo "Usage: ./validate-macos.sh [OPTIONS]"
|
| 17 |
+
echo ""
|
| 18 |
+
echo "Options:"
|
| 19 |
+
echo " --help Show this help message"
|
| 20 |
+
echo " --apple-id EMAIL Apple ID email for validation"
|
| 21 |
+
echo " --apple-password PWD App-specific password for Apple ID"
|
| 22 |
+
echo ""
|
| 23 |
+
echo "Environment variables:"
|
| 24 |
+
echo " APPLE_ID Apple ID email for validation"
|
| 25 |
+
echo " APPLE_PASSWORD App-specific password for Apple ID"
|
| 26 |
+
echo ""
|
| 27 |
+
echo "Notes:"
|
| 28 |
+
echo " - Command line options take precedence over environment variables"
|
| 29 |
+
echo " - Authentication is optional. If not provided, alternative validation will be performed"
|
| 30 |
+
echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
# Parse command line arguments
|
| 34 |
+
while [[ $# -gt 0 ]]; do
|
| 35 |
+
case $1 in
|
| 36 |
+
--help)
|
| 37 |
+
print_usage
|
| 38 |
+
exit 0
|
| 39 |
+
;;
|
| 40 |
+
--apple-id)
|
| 41 |
+
APPLE_ID="$2"
|
| 42 |
+
shift 2
|
| 43 |
+
;;
|
| 44 |
+
--apple-password)
|
| 45 |
+
APPLE_PASSWORD="$2"
|
| 46 |
+
shift 2
|
| 47 |
+
;;
|
| 48 |
+
*)
|
| 49 |
+
echo "Unknown option: $1"
|
| 50 |
+
print_usage
|
| 51 |
+
exit 1
|
| 52 |
+
;;
|
| 53 |
+
esac
|
| 54 |
+
done
|
| 55 |
+
|
| 56 |
+
# Function to clean up in case of error
|
| 57 |
+
cleanup() {
|
| 58 |
+
# Don't clean up temp files on error to help with debugging
|
| 59 |
+
echo "===== macOS Validation Process Failed ====="
|
| 60 |
+
exit 1
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
# Set up trap to call cleanup function on error
|
| 64 |
+
trap cleanup ERR
|
| 65 |
+
|
| 66 |
+
set -e # Exit on any error
|
| 67 |
+
|
| 68 |
+
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
|
| 69 |
+
BUILD_DIR="${ROOT_DIR}/validation-builds/ios"
|
| 70 |
+
|
| 71 |
+
# Configuration
|
| 72 |
+
APP_NAME="MacOSLlamaTest"
|
| 73 |
+
BUNDLE_ID="org.ggml.MacOSLlamaTest"
|
| 74 |
+
XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/llama.xcframework"
|
| 75 |
+
TEMP_DIR="${BUILD_DIR}/temp"
|
| 76 |
+
ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
|
| 77 |
+
APP_PATH="${BUILD_DIR}/${APP_NAME}.app"
|
| 78 |
+
ZIP_PATH="${BUILD_DIR}/${APP_NAME}.zip"
|
| 79 |
+
VALIDATION_DIR="${BUILD_DIR}/validation"
|
| 80 |
+
|
| 81 |
+
# Create necessary directories
|
| 82 |
+
mkdir -p "${BUILD_DIR}"
|
| 83 |
+
mkdir -p "${TEMP_DIR}"
|
| 84 |
+
mkdir -p "${VALIDATION_DIR}"
|
| 85 |
+
|
| 86 |
+
echo "===== macOS Validation Process Started ====="
|
| 87 |
+
|
| 88 |
+
# 1. Create a simple test app project
|
| 89 |
+
echo "Creating test macOS app project..."
|
| 90 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
|
| 91 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
|
| 92 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 93 |
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
| 94 |
+
<plist version="1.0">
|
| 95 |
+
<dict>
|
| 96 |
+
<key>CFBundleDevelopmentRegion</key>
|
| 97 |
+
<string>en</string>
|
| 98 |
+
<key>CFBundleExecutable</key>
|
| 99 |
+
<string>${APP_NAME}</string>
|
| 100 |
+
<key>CFBundleIdentifier</key>
|
| 101 |
+
<string>${BUNDLE_ID}</string>
|
| 102 |
+
<key>CFBundleInfoDictionaryVersion</key>
|
| 103 |
+
<string>6.0</string>
|
| 104 |
+
<key>CFBundleName</key>
|
| 105 |
+
<string>${APP_NAME}</string>
|
| 106 |
+
<key>CFBundlePackageType</key>
|
| 107 |
+
<string>APPL</string>
|
| 108 |
+
<key>CFBundleShortVersionString</key>
|
| 109 |
+
<string>1.0</string>
|
| 110 |
+
<key>CFBundleVersion</key>
|
| 111 |
+
<string>1</string>
|
| 112 |
+
<key>LSMinimumSystemVersion</key>
|
| 113 |
+
<string>12.0</string>
|
| 114 |
+
<key>NSHumanReadableCopyright</key>
|
| 115 |
+
<string>Copyright © 2025 GGML. All rights reserved.</string>
|
| 116 |
+
<key>NSPrincipalClass</key>
|
| 117 |
+
<string>NSApplication</string>
|
| 118 |
+
</dict>
|
| 119 |
+
</plist>
|
| 120 |
+
EOF
|
| 121 |
+
|
| 122 |
+
# Create SwiftUI app files
|
| 123 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
|
| 124 |
+
|
| 125 |
+
# Create App.swift
|
| 126 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
|
| 127 |
+
import SwiftUI
|
| 128 |
+
import llama
|
| 129 |
+
|
| 130 |
+
@main
|
| 131 |
+
struct LlamaTestApp: App {
|
| 132 |
+
var body: some Scene {
|
| 133 |
+
WindowGroup {
|
| 134 |
+
ContentView()
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
EOF
|
| 139 |
+
|
| 140 |
+
# Create ContentView.swift with macOS specific elements
|
| 141 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
|
| 142 |
+
import SwiftUI
|
| 143 |
+
import llama
|
| 144 |
+
|
| 145 |
+
struct ContentView: View {
|
| 146 |
+
// Test that we can initialize a llama context params struct
|
| 147 |
+
let params = llama_context_default_params()
|
| 148 |
+
|
| 149 |
+
var body: some View {
|
| 150 |
+
VStack(spacing: 20) {
|
| 151 |
+
Text("Llama Framework Test on macOS")
|
| 152 |
+
.font(.largeTitle)
|
| 153 |
+
.padding()
|
| 154 |
+
|
| 155 |
+
Text("llama_context_default_params() created successfully")
|
| 156 |
+
.font(.headline)
|
| 157 |
+
.multilineTextAlignment(.center)
|
| 158 |
+
.padding()
|
| 159 |
+
|
| 160 |
+
// Display some param values to confirm the framework is working
|
| 161 |
+
Text("n_ctx: \(params.n_ctx)")
|
| 162 |
+
.font(.body)
|
| 163 |
+
|
| 164 |
+
Text("n_batch: \(params.n_batch)")
|
| 165 |
+
.font(.body)
|
| 166 |
+
|
| 167 |
+
Spacer()
|
| 168 |
+
}
|
| 169 |
+
.padding()
|
| 170 |
+
.frame(width: 600, height: 400)
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
struct ContentView_Previews: PreviewProvider {
|
| 175 |
+
static var previews: some View {
|
| 176 |
+
ContentView()
|
| 177 |
+
}
|
| 178 |
+
}
|
| 179 |
+
EOF
|
| 180 |
+
|
| 181 |
+
# Create project.pbxproj, fixing the framework search paths issues
|
| 182 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
|
| 183 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 184 |
+
// !$*UTF8*$!
|
| 185 |
+
{
|
| 186 |
+
archiveVersion = 1;
|
| 187 |
+
classes = {
|
| 188 |
+
};
|
| 189 |
+
objectVersion = 54;
|
| 190 |
+
objects = {
|
| 191 |
+
|
| 192 |
+
/* Begin PBXBuildFile section */
|
| 193 |
+
11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
|
| 194 |
+
33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
|
| 195 |
+
55555555555555555555555 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 196 |
+
77777777777777777777777 /* llama.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 197 |
+
/* End PBXBuildFile section */
|
| 198 |
+
|
| 199 |
+
/* Begin PBXCopyFilesBuildPhase section */
|
| 200 |
+
88888888888888888888888 /* Embed Frameworks */ = {
|
| 201 |
+
isa = PBXCopyFilesBuildPhase;
|
| 202 |
+
buildActionMask = 2147483647;
|
| 203 |
+
dstPath = "";
|
| 204 |
+
dstSubfolderSpec = 10;
|
| 205 |
+
files = (
|
| 206 |
+
77777777777777777777777 /* llama.xcframework in Embed Frameworks */,
|
| 207 |
+
);
|
| 208 |
+
name = "Embed Frameworks";
|
| 209 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 210 |
+
};
|
| 211 |
+
/* End PBXCopyFilesBuildPhase section */
|
| 212 |
+
|
| 213 |
+
/* Begin PBXFileReference section */
|
| 214 |
+
EOF
|
| 215 |
+
|
| 216 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 217 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 218 |
+
99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 219 |
+
22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
|
| 220 |
+
44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
| 221 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
| 222 |
+
66666666666666666666666 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; };
|
| 223 |
+
/* End PBXFileReference section */
|
| 224 |
+
EOF
|
| 225 |
+
|
| 226 |
+
# Add the rest of the project file with fixed framework search paths
|
| 227 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 228 |
+
/* Begin PBXFrameworksBuildPhase section */
|
| 229 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
|
| 230 |
+
isa = PBXFrameworksBuildPhase;
|
| 231 |
+
buildActionMask = 2147483647;
|
| 232 |
+
files = (
|
| 233 |
+
55555555555555555555555 /* llama.xcframework in Frameworks */,
|
| 234 |
+
);
|
| 235 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 236 |
+
};
|
| 237 |
+
/* End PBXFrameworksBuildPhase section */
|
| 238 |
+
|
| 239 |
+
/* Begin PBXGroup section */
|
| 240 |
+
EOF
|
| 241 |
+
|
| 242 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 243 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 244 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
|
| 245 |
+
isa = PBXGroup;
|
| 246 |
+
children = (
|
| 247 |
+
99999999999999999999999 /* ${APP_NAME}.app */,
|
| 248 |
+
);
|
| 249 |
+
name = Products;
|
| 250 |
+
sourceTree = "<group>";
|
| 251 |
+
};
|
| 252 |
+
EOF
|
| 253 |
+
|
| 254 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 255 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
|
| 256 |
+
isa = PBXGroup;
|
| 257 |
+
children = (
|
| 258 |
+
66666666666666666666666 /* llama.xcframework */,
|
| 259 |
+
);
|
| 260 |
+
name = Frameworks;
|
| 261 |
+
sourceTree = "<group>";
|
| 262 |
+
};
|
| 263 |
+
EEEEEEEEEEEEEEEEEEEEEEEE = {
|
| 264 |
+
isa = PBXGroup;
|
| 265 |
+
children = (
|
| 266 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* MacOSLlamaTest */,
|
| 267 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
|
| 268 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
|
| 269 |
+
);
|
| 270 |
+
sourceTree = "<group>";
|
| 271 |
+
};
|
| 272 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* MacOSLlamaTest */ = {
|
| 273 |
+
isa = PBXGroup;
|
| 274 |
+
children = (
|
| 275 |
+
1111111111111111111111AA /* Sources */,
|
| 276 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
|
| 277 |
+
);
|
| 278 |
+
path = "MacOSLlamaTest";
|
| 279 |
+
sourceTree = "<group>";
|
| 280 |
+
};
|
| 281 |
+
1111111111111111111111AA /* Sources */ = {
|
| 282 |
+
isa = PBXGroup;
|
| 283 |
+
children = (
|
| 284 |
+
22222222222222222222222 /* App.swift */,
|
| 285 |
+
44444444444444444444444 /* ContentView.swift */,
|
| 286 |
+
);
|
| 287 |
+
path = Sources;
|
| 288 |
+
sourceTree = "<group>";
|
| 289 |
+
};
|
| 290 |
+
/* End PBXGroup section */
|
| 291 |
+
EOF
|
| 292 |
+
|
| 293 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 294 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 295 |
+
/* Begin PBXNativeTarget section */
|
| 296 |
+
3333333333333333333333AA /* ${APP_NAME} */ = {
|
| 297 |
+
isa = PBXNativeTarget;
|
| 298 |
+
buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
|
| 299 |
+
buildPhases = (
|
| 300 |
+
5555555555555555555555AA /* Sources */,
|
| 301 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
|
| 302 |
+
6666666666666666666666AA /* Resources */,
|
| 303 |
+
88888888888888888888888 /* Embed Frameworks */,
|
| 304 |
+
);
|
| 305 |
+
buildRules = (
|
| 306 |
+
);
|
| 307 |
+
dependencies = (
|
| 308 |
+
);
|
| 309 |
+
name = "${APP_NAME}";
|
| 310 |
+
productName = "${APP_NAME}";
|
| 311 |
+
productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
|
| 312 |
+
productType = "com.apple.product-type.application";
|
| 313 |
+
};
|
| 314 |
+
/* End PBXNativeTarget section */
|
| 315 |
+
|
| 316 |
+
/* Begin PBXProject section */
|
| 317 |
+
7777777777777777777777AA /* Project object */ = {
|
| 318 |
+
isa = PBXProject;
|
| 319 |
+
attributes = {
|
| 320 |
+
LastSwiftUpdateCheck = 1240;
|
| 321 |
+
LastUpgradeCheck = 1240;
|
| 322 |
+
TargetAttributes = {
|
| 323 |
+
3333333333333333333333AA = {
|
| 324 |
+
CreatedOnToolsVersion = 12.4;
|
| 325 |
+
};
|
| 326 |
+
};
|
| 327 |
+
};
|
| 328 |
+
buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
|
| 329 |
+
compatibilityVersion = "Xcode 12.0";
|
| 330 |
+
developmentRegion = en;
|
| 331 |
+
hasScannedForEncodings = 0;
|
| 332 |
+
knownRegions = (
|
| 333 |
+
en,
|
| 334 |
+
Base,
|
| 335 |
+
);
|
| 336 |
+
mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
|
| 337 |
+
productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
|
| 338 |
+
projectDirPath = "";
|
| 339 |
+
projectRoot = "";
|
| 340 |
+
targets = (
|
| 341 |
+
3333333333333333333333AA /* ${APP_NAME} */,
|
| 342 |
+
);
|
| 343 |
+
};
|
| 344 |
+
/* End PBXProject section */
|
| 345 |
+
EOF
|
| 346 |
+
|
| 347 |
+
# Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS and macOS settings
|
| 348 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 349 |
+
/* Begin PBXResourcesBuildPhase section */
|
| 350 |
+
6666666666666666666666AA /* Resources */ = {
|
| 351 |
+
isa = PBXResourcesBuildPhase;
|
| 352 |
+
buildActionMask = 2147483647;
|
| 353 |
+
files = (
|
| 354 |
+
);
|
| 355 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 356 |
+
};
|
| 357 |
+
/* End PBXResourcesBuildPhase section */
|
| 358 |
+
|
| 359 |
+
/* Begin PBXSourcesBuildPhase section */
|
| 360 |
+
5555555555555555555555AA /* Sources */ = {
|
| 361 |
+
isa = PBXSourcesBuildPhase;
|
| 362 |
+
buildActionMask = 2147483647;
|
| 363 |
+
files = (
|
| 364 |
+
33333333333333333333333 /* ContentView.swift in Sources */,
|
| 365 |
+
11111111111111111111111 /* App.swift in Sources */,
|
| 366 |
+
);
|
| 367 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 368 |
+
};
|
| 369 |
+
/* End PBXSourcesBuildPhase section */
|
| 370 |
+
|
| 371 |
+
/* Begin XCBuildConfiguration section */
|
| 372 |
+
9999999999999999999999AA /* Debug */ = {
|
| 373 |
+
isa = XCBuildConfiguration;
|
| 374 |
+
buildSettings = {
|
| 375 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 376 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 377 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 378 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 379 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 380 |
+
CLANG_ENABLE_MODULES = YES;
|
| 381 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 382 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 383 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 384 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 385 |
+
CLANG_WARN_COMMA = YES;
|
| 386 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 387 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 388 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 389 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 390 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 391 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 392 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 393 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 394 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 395 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 396 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 397 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 398 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 399 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 400 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 401 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 402 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 403 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 404 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 405 |
+
COPY_PHASE_STRIP = NO;
|
| 406 |
+
DEBUG_INFORMATION_FORMAT = dwarf;
|
| 407 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 408 |
+
ENABLE_TESTABILITY = YES;
|
| 409 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 410 |
+
GCC_DYNAMIC_NO_PIC = NO;
|
| 411 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 412 |
+
GCC_OPTIMIZATION_LEVEL = 0;
|
| 413 |
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
| 414 |
+
"DEBUG=1",
|
| 415 |
+
"$(inherited)",
|
| 416 |
+
);
|
| 417 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 418 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 419 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 420 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 421 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 422 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 423 |
+
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
| 424 |
+
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
| 425 |
+
MTL_FAST_MATH = YES;
|
| 426 |
+
ONLY_ACTIVE_ARCH = YES;
|
| 427 |
+
SDKROOT = macosx;
|
| 428 |
+
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
| 429 |
+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
| 430 |
+
};
|
| 431 |
+
name = Debug;
|
| 432 |
+
};
|
| 433 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
|
| 434 |
+
isa = XCBuildConfiguration;
|
| 435 |
+
buildSettings = {
|
| 436 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 437 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 438 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 439 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 440 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 441 |
+
CLANG_ENABLE_MODULES = YES;
|
| 442 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 443 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 444 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 445 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 446 |
+
CLANG_WARN_COMMA = YES;
|
| 447 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 448 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 449 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 450 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 451 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 452 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 453 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 454 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 455 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 456 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 457 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 458 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 459 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 460 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 461 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 462 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 463 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 464 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 465 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 466 |
+
COPY_PHASE_STRIP = NO;
|
| 467 |
+
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
| 468 |
+
ENABLE_NS_ASSERTIONS = NO;
|
| 469 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 470 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 471 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 472 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 473 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 474 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 475 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 476 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 477 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 478 |
+
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
| 479 |
+
MTL_ENABLE_DEBUG_INFO = NO;
|
| 480 |
+
MTL_FAST_MATH = YES;
|
| 481 |
+
SDKROOT = macosx;
|
| 482 |
+
SWIFT_COMPILATION_MODE = wholemodule;
|
| 483 |
+
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
| 484 |
+
};
|
| 485 |
+
name = Release;
|
| 486 |
+
};
|
| 487 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
|
| 488 |
+
isa = XCBuildConfiguration;
|
| 489 |
+
buildSettings = {
|
| 490 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 491 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 492 |
+
CODE_SIGN_STYLE = Manual;
|
| 493 |
+
COMBINE_HIDPI_IMAGES = YES;
|
| 494 |
+
DEVELOPMENT_TEAM = "";
|
| 495 |
+
ENABLE_HARDENED_RUNTIME = YES;
|
| 496 |
+
ENABLE_PREVIEWS = YES;
|
| 497 |
+
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
| 498 |
+
INFOPLIST_FILE = "MacOSLlamaTest/Info.plist";
|
| 499 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 500 |
+
"$(inherited)",
|
| 501 |
+
"@executable_path/../Frameworks",
|
| 502 |
+
);
|
| 503 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.MacOSLlamaTest";
|
| 504 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 505 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 506 |
+
SWIFT_VERSION = 5.0;
|
| 507 |
+
};
|
| 508 |
+
name = Debug;
|
| 509 |
+
};
|
| 510 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
|
| 511 |
+
isa = XCBuildConfiguration;
|
| 512 |
+
buildSettings = {
|
| 513 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 514 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 515 |
+
CODE_SIGN_STYLE = Manual;
|
| 516 |
+
COMBINE_HIDPI_IMAGES = YES;
|
| 517 |
+
DEVELOPMENT_TEAM = "";
|
| 518 |
+
ENABLE_HARDENED_RUNTIME = YES;
|
| 519 |
+
ENABLE_PREVIEWS = YES;
|
| 520 |
+
FRAMEWORK_SEARCH_PATHS = (
|
| 521 |
+
"$(inherited)",
|
| 522 |
+
"$(PROJECT_DIR)",
|
| 523 |
+
);
|
| 524 |
+
INFOPLIST_FILE = "MacOSLlamaTest/Info.plist";
|
| 525 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 526 |
+
"$(inherited)",
|
| 527 |
+
"@executable_path/../Frameworks",
|
| 528 |
+
);
|
| 529 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.MacOSLlamaTest";
|
| 530 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 531 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 532 |
+
SWIFT_VERSION = 5.0;
|
| 533 |
+
};
|
| 534 |
+
name = Release;
|
| 535 |
+
};
|
| 536 |
+
/* End XCBuildConfiguration section */
|
| 537 |
+
EOF
|
| 538 |
+
|
| 539 |
+
# Finish the project.pbxproj file
|
| 540 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 541 |
+
/* Begin XCConfigurationList section */
|
| 542 |
+
8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
|
| 543 |
+
isa = XCConfigurationList;
|
| 544 |
+
buildConfigurations = (
|
| 545 |
+
9999999999999999999999AA /* Debug */,
|
| 546 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
|
| 547 |
+
);
|
| 548 |
+
defaultConfigurationIsVisible = 0;
|
| 549 |
+
defaultConfigurationName = Release;
|
| 550 |
+
};
|
| 551 |
+
4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
|
| 552 |
+
isa = XCConfigurationList;
|
| 553 |
+
buildConfigurations = (
|
| 554 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
|
| 555 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
|
| 556 |
+
);
|
| 557 |
+
defaultConfigurationIsVisible = 0;
|
| 558 |
+
defaultConfigurationName = Release;
|
| 559 |
+
};
|
| 560 |
+
/* End XCConfigurationList section */
|
| 561 |
+
};
|
| 562 |
+
rootObject = 7777777777777777777777AA /* Project object */;
|
| 563 |
+
}
|
| 564 |
+
EOF
|
| 565 |
+
|
| 566 |
+
# 2. Copy XCFramework to test project
|
| 567 |
+
echo "Copying XCFramework to test project..."
|
| 568 |
+
cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
|
| 569 |
+
|
| 570 |
+
# 3. Build and archive the app
|
| 571 |
+
echo "Building and archiving test app..."
|
| 572 |
+
cd "${TEMP_DIR}/${APP_NAME}"
|
| 573 |
+
|
| 574 |
+
# Create a simple xcscheme file to avoid xcodebuild scheme issues
|
| 575 |
+
mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
|
| 576 |
+
cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
|
| 577 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 578 |
+
<Scheme
|
| 579 |
+
LastUpgradeVersion = "1240"
|
| 580 |
+
version = "1.3">
|
| 581 |
+
<BuildAction
|
| 582 |
+
parallelizeBuildables = "YES"
|
| 583 |
+
buildImplicitDependencies = "YES">
|
| 584 |
+
<BuildActionEntries>
|
| 585 |
+
<BuildActionEntry
|
| 586 |
+
buildForTesting = "YES"
|
| 587 |
+
buildForRunning = "YES"
|
| 588 |
+
buildForProfiling = "YES"
|
| 589 |
+
buildForArchiving = "YES"
|
| 590 |
+
buildForAnalyzing = "YES">
|
| 591 |
+
<BuildableReference
|
| 592 |
+
BuildableIdentifier = "primary"
|
| 593 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 594 |
+
BuildableName = "${APP_NAME}.app"
|
| 595 |
+
BlueprintName = "${APP_NAME}"
|
| 596 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 597 |
+
</BuildableReference>
|
| 598 |
+
</BuildActionEntry>
|
| 599 |
+
</BuildActionEntries>
|
| 600 |
+
</BuildAction>
|
| 601 |
+
<TestAction
|
| 602 |
+
buildConfiguration = "Debug"
|
| 603 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 604 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 605 |
+
shouldUseLaunchSchemeArgsEnv = "YES">
|
| 606 |
+
<Testables>
|
| 607 |
+
</Testables>
|
| 608 |
+
</TestAction>
|
| 609 |
+
<LaunchAction
|
| 610 |
+
buildConfiguration = "Debug"
|
| 611 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 612 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 613 |
+
launchStyle = "0"
|
| 614 |
+
useCustomWorkingDirectory = "NO"
|
| 615 |
+
ignoresPersistentStateOnLaunch = "NO"
|
| 616 |
+
debugDocumentVersioning = "YES"
|
| 617 |
+
debugServiceExtension = "internal"
|
| 618 |
+
allowLocationSimulation = "YES">
|
| 619 |
+
<BuildableProductRunnable
|
| 620 |
+
runnableDebuggingMode = "0">
|
| 621 |
+
<BuildableReference
|
| 622 |
+
BuildableIdentifier = "primary"
|
| 623 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 624 |
+
BuildableName = "${APP_NAME}.app"
|
| 625 |
+
BlueprintName = "${APP_NAME}"
|
| 626 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 627 |
+
</BuildableReference>
|
| 628 |
+
</BuildableProductRunnable>
|
| 629 |
+
</LaunchAction>
|
| 630 |
+
<ProfileAction
|
| 631 |
+
buildConfiguration = "Release"
|
| 632 |
+
shouldUseLaunchSchemeArgsEnv = "YES"
|
| 633 |
+
savedToolIdentifier = ""
|
| 634 |
+
useCustomWorkingDirectory = "NO"
|
| 635 |
+
debugDocumentVersioning = "YES">
|
| 636 |
+
<BuildableProductRunnable
|
| 637 |
+
runnableDebuggingMode = "0">
|
| 638 |
+
<BuildableReference
|
| 639 |
+
BuildableIdentifier = "primary"
|
| 640 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 641 |
+
BuildableName = "${APP_NAME}.app"
|
| 642 |
+
BlueprintName = "${APP_NAME}"
|
| 643 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 644 |
+
</BuildableReference>
|
| 645 |
+
</BuildableProductRunnable>
|
| 646 |
+
</ProfileAction>
|
| 647 |
+
<AnalyzeAction
|
| 648 |
+
buildConfiguration = "Debug">
|
| 649 |
+
</AnalyzeAction>
|
| 650 |
+
<ArchiveAction
|
| 651 |
+
buildConfiguration = "Release"
|
| 652 |
+
revealArchiveInOrganizer = "YES">
|
| 653 |
+
</ArchiveAction>
|
| 654 |
+
</Scheme>
|
| 655 |
+
EOF
|
| 656 |
+
|
| 657 |
+
# Now use xcodebuild with an explicitly defined product name for macOS
|
| 658 |
+
xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk macosx -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
|
| 659 |
+
|
| 660 |
+
# 4. Create a package for distribution
|
| 661 |
+
echo "Creating distributable package from archive..."
|
| 662 |
+
cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${APP_PATH}"
|
| 663 |
+
|
| 664 |
+
# Check and log app structure
|
| 665 |
+
echo "App structure:"
|
| 666 |
+
ls -la "${APP_PATH}"
|
| 667 |
+
echo "Frameworks:"
|
| 668 |
+
ls -la "${APP_PATH}/Contents/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 669 |
+
|
| 670 |
+
# Create a zip file for potential distribution
|
| 671 |
+
cd "${BUILD_DIR}"
|
| 672 |
+
zip -r "${ZIP_PATH}" "${APP_NAME}.app"
|
| 673 |
+
|
| 674 |
+
# Check embedded provisioning profile
|
| 675 |
+
echo "Checking provisioning profile (if any)..."
|
| 676 |
+
PROVISIONING_PROFILE=$(find "${APP_PATH}/Contents" -name "embedded.provisionprofile" 2>/dev/null)
|
| 677 |
+
if [ -n "$PROVISIONING_PROFILE" ]; then
|
| 678 |
+
echo "Found embedded provisioning profile:"
|
| 679 |
+
security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
|
| 680 |
+
else
|
| 681 |
+
echo "No embedded provisioning profile found (expected for ad-hoc builds)"
|
| 682 |
+
fi
|
| 683 |
+
|
| 684 |
+
# 5. Validate the app
|
| 685 |
+
echo "Validating macOS app..."
|
| 686 |
+
VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
|
| 687 |
+
|
| 688 |
+
# Check if authentication credentials are provided
|
| 689 |
+
AUTH_ARGS=""
|
| 690 |
+
if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
|
| 691 |
+
echo "Using Apple ID authentication for validation..."
|
| 692 |
+
AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
|
| 693 |
+
else
|
| 694 |
+
echo "No authentication credentials provided. Will perform basic validation."
|
| 695 |
+
echo "To use your personal developer account, you can run the script with:"
|
| 696 |
+
echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-macos.sh"
|
| 697 |
+
echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
|
| 698 |
+
fi
|
| 699 |
+
|
| 700 |
+
# For macOS we need to use notarytool or alternative checks because altool doesn't support macOS apps in the same way
|
| 701 |
+
echo "Note: For macOS, formal notarization process would require Apple Developer credentials."
|
| 702 |
+
echo "Performing alternative validation checks..."
|
| 703 |
+
|
| 704 |
+
# Final validation result
|
| 705 |
+
FINAL_VALIDATION_RESULT=0
|
| 706 |
+
|
| 707 |
+
# Check if app was created successfully
|
| 708 |
+
if [ -d "${APP_PATH}" ] && [ -s "${APP_PATH}/Contents/MacOS/${APP_NAME}" ]; then
|
| 709 |
+
echo "✅ App package created successfully"
|
| 710 |
+
else
|
| 711 |
+
echo "❌ App package not created or binary missing"
|
| 712 |
+
FINAL_VALIDATION_RESULT=1
|
| 713 |
+
fi
|
| 714 |
+
|
| 715 |
+
# Check if app binary exists and is executable
|
| 716 |
+
if [ -f "${APP_PATH}/Contents/MacOS/${APP_NAME}" ] && [ -x "${APP_PATH}/Contents/MacOS/${APP_NAME}" ]; then
|
| 717 |
+
echo "✅ App binary exists and is executable"
|
| 718 |
+
else
|
| 719 |
+
echo "❌ App binary missing or not executable"
|
| 720 |
+
FINAL_VALIDATION_RESULT=1
|
| 721 |
+
fi
|
| 722 |
+
|
| 723 |
+
# Check if framework was properly embedded
|
| 724 |
+
if [ -d "${APP_PATH}/Contents/Frameworks/llama.framework" ]; then
|
| 725 |
+
echo "✅ llama.framework properly embedded"
|
| 726 |
+
else
|
| 727 |
+
echo "❌ llama.framework not properly embedded"
|
| 728 |
+
FINAL_VALIDATION_RESULT=1
|
| 729 |
+
fi
|
| 730 |
+
|
| 731 |
+
# Check if framework binary exists
|
| 732 |
+
if [ -f "${APP_PATH}/Contents/Frameworks/llama.framework/Versions/A/llama" ]; then
|
| 733 |
+
echo "✅ Framework binary exists"
|
| 734 |
+
|
| 735 |
+
# Further validate framework by checking architecture
|
| 736 |
+
ARCHS=$(lipo -info "${APP_PATH}/Contents/Frameworks/llama.framework/Versions/A/llama" 2>/dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ')
|
| 737 |
+
if [ -n "$ARCHS" ]; then
|
| 738 |
+
echo "✅ Framework architecture(s): $ARCHS"
|
| 739 |
+
else
|
| 740 |
+
echo "⚠️ Could not determine framework architecture"
|
| 741 |
+
fi
|
| 742 |
+
else
|
| 743 |
+
echo "❌ Framework binary missing"
|
| 744 |
+
FINAL_VALIDATION_RESULT=1
|
| 745 |
+
fi
|
| 746 |
+
|
| 747 |
+
# Check code signing
|
| 748 |
+
echo ""
|
| 749 |
+
echo "==== CODE SIGNING INFO ===="
|
| 750 |
+
codesign -vv -d "${APP_PATH}" 2>&1 || echo "Code signing verification not available (expected for ad-hoc builds)"
|
| 751 |
+
|
| 752 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 753 |
+
if [ -n "$AUTH_ARGS" ]; then
|
| 754 |
+
echo ""
|
| 755 |
+
echo "To notarize this app with Apple (requires Apple Developer account):"
|
| 756 |
+
echo "xcrun notarytool submit \"${ZIP_PATH}\" --apple-id \"your-apple-id\" --password \"your-app-specific-password\" --team-id \"your-team-id\" --wait"
|
| 757 |
+
echo ""
|
| 758 |
+
fi
|
| 759 |
+
echo "✅ Validation PASSED: macOS app built successfully with embedded framework"
|
| 760 |
+
else
|
| 761 |
+
echo "❌ Validation FAILED: Issues found with the app or framework"
|
| 762 |
+
fi
|
| 763 |
+
|
| 764 |
+
# Don't clean up on error to allow inspection
|
| 765 |
+
if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
|
| 766 |
+
echo ""
|
| 767 |
+
echo "Temporary files kept for inspection at: ${TEMP_DIR}"
|
| 768 |
+
echo "===== macOS Validation Process Failed ====="
|
| 769 |
+
exit 1
|
| 770 |
+
fi
|
| 771 |
+
|
| 772 |
+
# Clean up temporary files but keep build artifacts
|
| 773 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 774 |
+
echo "Cleaning up temporary files..."
|
| 775 |
+
#rm -rf "${TEMP_DIR}"
|
| 776 |
+
fi
|
| 777 |
+
|
| 778 |
+
echo "===== macOS Validation Process Completed ====="
|
| 779 |
+
echo "App package available at: ${APP_PATH}"
|
| 780 |
+
echo "Zipped app available at: ${ZIP_PATH}"
|
| 781 |
+
exit $FINAL_VALIDATION_RESULT
|
llama.cpp/scripts/apple/validate-tvos.sh
ADDED
|
@@ -0,0 +1,813 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
# validate-tvos.sh - Validate tvOS Application with embedded llama.xcframework using SwiftUI
|
| 3 |
+
|
| 4 |
+
# Authentication options (optional) (can be set via environment variables)
|
| 5 |
+
# To use: export APPLE_ID=your.email@example.com
|
| 6 |
+
# export APPLE_PASSWORD=your-app-specific-password
|
| 7 |
+
# ./validate-tvos.sh
|
| 8 |
+
APPLE_ID=${APPLE_ID:-""}
|
| 9 |
+
APPLE_PASSWORD=${APPLE_PASSWORD:-""}
|
| 10 |
+
|
| 11 |
+
# Ensure the script exits on error
|
| 12 |
+
set -e
|
| 13 |
+
|
| 14 |
+
# Function to print usage instructions
|
| 15 |
+
print_usage() {
|
| 16 |
+
echo "Usage: ./validate-tvos.sh [OPTIONS]"
|
| 17 |
+
echo ""
|
| 18 |
+
echo "Options:"
|
| 19 |
+
echo " --help Show this help message"
|
| 20 |
+
echo " --apple-id EMAIL Apple ID email for validation"
|
| 21 |
+
echo " --apple-password PWD App-specific password for Apple ID"
|
| 22 |
+
echo ""
|
| 23 |
+
echo "Environment variables:"
|
| 24 |
+
echo " APPLE_ID Apple ID email for validation"
|
| 25 |
+
echo " APPLE_PASSWORD App-specific password for Apple ID"
|
| 26 |
+
echo ""
|
| 27 |
+
echo "Notes:"
|
| 28 |
+
echo " - Command line options take precedence over environment variables"
|
| 29 |
+
echo " - Authentication is optional. If not provided, alternative validation will be performed"
|
| 30 |
+
echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
# Parse command line arguments
|
| 34 |
+
while [[ $# -gt 0 ]]; do
|
| 35 |
+
case $1 in
|
| 36 |
+
--help)
|
| 37 |
+
print_usage
|
| 38 |
+
exit 0
|
| 39 |
+
;;
|
| 40 |
+
--apple-id)
|
| 41 |
+
APPLE_ID="$2"
|
| 42 |
+
shift 2
|
| 43 |
+
;;
|
| 44 |
+
--apple-password)
|
| 45 |
+
APPLE_PASSWORD="$2"
|
| 46 |
+
shift 2
|
| 47 |
+
;;
|
| 48 |
+
*)
|
| 49 |
+
echo "Unknown option: $1"
|
| 50 |
+
print_usage
|
| 51 |
+
exit 1
|
| 52 |
+
;;
|
| 53 |
+
esac
|
| 54 |
+
done
|
| 55 |
+
|
| 56 |
+
# Function to clean up in case of error
|
| 57 |
+
cleanup() {
|
| 58 |
+
# Don't clean up temp files on error to help with debugging
|
| 59 |
+
echo "===== tvOS Validation Process Failed ====="
|
| 60 |
+
exit 1
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
# Set up trap to call cleanup function on error
|
| 64 |
+
trap cleanup ERR
|
| 65 |
+
|
| 66 |
+
set -e # Exit on any error
|
| 67 |
+
|
| 68 |
+
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
|
| 69 |
+
BUILD_DIR="${ROOT_DIR}/validation-builds/ios"
|
| 70 |
+
|
| 71 |
+
# Configuration
|
| 72 |
+
APP_NAME="TVOSLlamaTest"
|
| 73 |
+
BUNDLE_ID="org.ggml.TVOSLlamaTest"
|
| 74 |
+
XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/llama.xcframework"
|
| 75 |
+
TEMP_DIR="${BUILD_DIR}/temp"
|
| 76 |
+
ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
|
| 77 |
+
IPA_PATH="${BUILD_DIR}/${APP_NAME}.ipa"
|
| 78 |
+
VALIDATION_DIR="${BUILD_DIR}/validation"
|
| 79 |
+
|
| 80 |
+
# Create necessary directories
|
| 81 |
+
mkdir -p "${BUILD_DIR}"
|
| 82 |
+
mkdir -p "${TEMP_DIR}"
|
| 83 |
+
mkdir -p "${VALIDATION_DIR}"
|
| 84 |
+
|
| 85 |
+
echo "===== tvOS Validation Process Started ====="
|
| 86 |
+
|
| 87 |
+
# 1. Create a simple test app project
|
| 88 |
+
echo "Creating test tvOS app project..."
|
| 89 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
|
| 90 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
|
| 91 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 92 |
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
| 93 |
+
<plist version="1.0">
|
| 94 |
+
<dict>
|
| 95 |
+
<key>CFBundleDevelopmentRegion</key>
|
| 96 |
+
<string>en</string>
|
| 97 |
+
<key>CFBundleExecutable</key>
|
| 98 |
+
<string>${APP_NAME}</string>
|
| 99 |
+
<key>CFBundleIdentifier</key>
|
| 100 |
+
<string>${BUNDLE_ID}</string>
|
| 101 |
+
<key>CFBundleInfoDictionaryVersion</key>
|
| 102 |
+
<string>6.0</string>
|
| 103 |
+
<key>CFBundleName</key>
|
| 104 |
+
<string>${APP_NAME}</string>
|
| 105 |
+
<key>CFBundlePackageType</key>
|
| 106 |
+
<string>APPL</string>
|
| 107 |
+
<key>CFBundleShortVersionString</key>
|
| 108 |
+
<string>1.0</string>
|
| 109 |
+
<key>CFBundleVersion</key>
|
| 110 |
+
<string>1</string>
|
| 111 |
+
<key>UIRequiredDeviceCapabilities</key>
|
| 112 |
+
<array>
|
| 113 |
+
<string>arm64</string>
|
| 114 |
+
</array>
|
| 115 |
+
</dict>
|
| 116 |
+
</plist>
|
| 117 |
+
EOF
|
| 118 |
+
|
| 119 |
+
# Create SwiftUI app files
|
| 120 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
|
| 121 |
+
|
| 122 |
+
# Create App.swift
|
| 123 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
|
| 124 |
+
import SwiftUI
|
| 125 |
+
import llama
|
| 126 |
+
|
| 127 |
+
@main
|
| 128 |
+
struct LlamaTestApp: App {
|
| 129 |
+
var body: some Scene {
|
| 130 |
+
WindowGroup {
|
| 131 |
+
ContentView()
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
}
|
| 135 |
+
EOF
|
| 136 |
+
|
| 137 |
+
# Create ContentView.swift with tvOS specific elements
|
| 138 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
|
| 139 |
+
import SwiftUI
|
| 140 |
+
import llama
|
| 141 |
+
|
| 142 |
+
struct ContentView: View {
|
| 143 |
+
// Test that we can initialize a llama context params struct
|
| 144 |
+
let params = llama_context_default_params()
|
| 145 |
+
|
| 146 |
+
var body: some View {
|
| 147 |
+
VStack(spacing: 40) {
|
| 148 |
+
Text("Llama Framework Test on tvOS")
|
| 149 |
+
.font(.largeTitle)
|
| 150 |
+
.padding()
|
| 151 |
+
|
| 152 |
+
Text("llama_context_default_params() created successfully")
|
| 153 |
+
.font(.headline)
|
| 154 |
+
.multilineTextAlignment(.center)
|
| 155 |
+
.padding()
|
| 156 |
+
|
| 157 |
+
// Display some param values to confirm the framework is working
|
| 158 |
+
Text("n_ctx: \(params.n_ctx)")
|
| 159 |
+
.font(.title2)
|
| 160 |
+
|
| 161 |
+
Text("n_batch: \(params.n_batch)")
|
| 162 |
+
.font(.title2)
|
| 163 |
+
|
| 164 |
+
Spacer()
|
| 165 |
+
}
|
| 166 |
+
.padding(50)
|
| 167 |
+
// Larger size suitable for TV display
|
| 168 |
+
}
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
struct ContentView_Previews: PreviewProvider {
|
| 172 |
+
static var previews: some View {
|
| 173 |
+
ContentView()
|
| 174 |
+
}
|
| 175 |
+
}
|
| 176 |
+
EOF
|
| 177 |
+
|
| 178 |
+
# Create project.pbxproj, fixing the framework search paths issues
|
| 179 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
|
| 180 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 181 |
+
// !$*UTF8*$!
|
| 182 |
+
{
|
| 183 |
+
archiveVersion = 1;
|
| 184 |
+
classes = {
|
| 185 |
+
};
|
| 186 |
+
objectVersion = 54;
|
| 187 |
+
objects = {
|
| 188 |
+
|
| 189 |
+
/* Begin PBXBuildFile section */
|
| 190 |
+
11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
|
| 191 |
+
33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
|
| 192 |
+
55555555555555555555555 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 193 |
+
77777777777777777777777 /* llama.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 194 |
+
/* End PBXBuildFile section */
|
| 195 |
+
|
| 196 |
+
/* Begin PBXCopyFilesBuildPhase section */
|
| 197 |
+
88888888888888888888888 /* Embed Frameworks */ = {
|
| 198 |
+
isa = PBXCopyFilesBuildPhase;
|
| 199 |
+
buildActionMask = 2147483647;
|
| 200 |
+
dstPath = "";
|
| 201 |
+
dstSubfolderSpec = 10;
|
| 202 |
+
files = (
|
| 203 |
+
77777777777777777777777 /* llama.xcframework in Embed Frameworks */,
|
| 204 |
+
);
|
| 205 |
+
name = "Embed Frameworks";
|
| 206 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 207 |
+
};
|
| 208 |
+
/* End PBXCopyFilesBuildPhase section */
|
| 209 |
+
|
| 210 |
+
/* Begin PBXFileReference section */
|
| 211 |
+
EOF
|
| 212 |
+
|
| 213 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 214 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 215 |
+
99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 216 |
+
22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
|
| 217 |
+
44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
| 218 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
| 219 |
+
66666666666666666666666 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; };
|
| 220 |
+
/* End PBXFileReference section */
|
| 221 |
+
EOF
|
| 222 |
+
|
| 223 |
+
# Add the rest of the project file with fixed framework search paths
|
| 224 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 225 |
+
/* Begin PBXFrameworksBuildPhase section */
|
| 226 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
|
| 227 |
+
isa = PBXFrameworksBuildPhase;
|
| 228 |
+
buildActionMask = 2147483647;
|
| 229 |
+
files = (
|
| 230 |
+
55555555555555555555555 /* llama.xcframework in Frameworks */,
|
| 231 |
+
);
|
| 232 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 233 |
+
};
|
| 234 |
+
/* End PBXFrameworksBuildPhase section */
|
| 235 |
+
|
| 236 |
+
/* Begin PBXGroup section */
|
| 237 |
+
EOF
|
| 238 |
+
|
| 239 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 240 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 241 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
|
| 242 |
+
isa = PBXGroup;
|
| 243 |
+
children = (
|
| 244 |
+
99999999999999999999999 /* ${APP_NAME}.app */,
|
| 245 |
+
);
|
| 246 |
+
name = Products;
|
| 247 |
+
sourceTree = "<group>";
|
| 248 |
+
};
|
| 249 |
+
EOF
|
| 250 |
+
|
| 251 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 252 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
|
| 253 |
+
isa = PBXGroup;
|
| 254 |
+
children = (
|
| 255 |
+
66666666666666666666666 /* llama.xcframework */,
|
| 256 |
+
);
|
| 257 |
+
name = Frameworks;
|
| 258 |
+
sourceTree = "<group>";
|
| 259 |
+
};
|
| 260 |
+
EEEEEEEEEEEEEEEEEEEEEEEE = {
|
| 261 |
+
isa = PBXGroup;
|
| 262 |
+
children = (
|
| 263 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* TVOSLlamaTest */,
|
| 264 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
|
| 265 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
|
| 266 |
+
);
|
| 267 |
+
sourceTree = "<group>";
|
| 268 |
+
};
|
| 269 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* TVOSLlamaTest */ = {
|
| 270 |
+
isa = PBXGroup;
|
| 271 |
+
children = (
|
| 272 |
+
1111111111111111111111AA /* Sources */,
|
| 273 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
|
| 274 |
+
);
|
| 275 |
+
path = "TVOSLlamaTest";
|
| 276 |
+
sourceTree = "<group>";
|
| 277 |
+
};
|
| 278 |
+
1111111111111111111111AA /* Sources */ = {
|
| 279 |
+
isa = PBXGroup;
|
| 280 |
+
children = (
|
| 281 |
+
22222222222222222222222 /* App.swift */,
|
| 282 |
+
44444444444444444444444 /* ContentView.swift */,
|
| 283 |
+
);
|
| 284 |
+
path = Sources;
|
| 285 |
+
sourceTree = "<group>";
|
| 286 |
+
};
|
| 287 |
+
/* End PBXGroup section */
|
| 288 |
+
EOF
|
| 289 |
+
|
| 290 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 291 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 292 |
+
/* Begin PBXNativeTarget section */
|
| 293 |
+
3333333333333333333333AA /* ${APP_NAME} */ = {
|
| 294 |
+
isa = PBXNativeTarget;
|
| 295 |
+
buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
|
| 296 |
+
buildPhases = (
|
| 297 |
+
5555555555555555555555AA /* Sources */,
|
| 298 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
|
| 299 |
+
6666666666666666666666AA /* Resources */,
|
| 300 |
+
88888888888888888888888 /* Embed Frameworks */,
|
| 301 |
+
);
|
| 302 |
+
buildRules = (
|
| 303 |
+
);
|
| 304 |
+
dependencies = (
|
| 305 |
+
);
|
| 306 |
+
name = "${APP_NAME}";
|
| 307 |
+
productName = "${APP_NAME}";
|
| 308 |
+
productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
|
| 309 |
+
productType = "com.apple.product-type.application";
|
| 310 |
+
};
|
| 311 |
+
/* End PBXNativeTarget section */
|
| 312 |
+
|
| 313 |
+
/* Begin PBXProject section */
|
| 314 |
+
7777777777777777777777AA /* Project object */ = {
|
| 315 |
+
isa = PBXProject;
|
| 316 |
+
attributes = {
|
| 317 |
+
LastSwiftUpdateCheck = 1240;
|
| 318 |
+
LastUpgradeCheck = 1240;
|
| 319 |
+
TargetAttributes = {
|
| 320 |
+
3333333333333333333333AA = {
|
| 321 |
+
CreatedOnToolsVersion = 12.4;
|
| 322 |
+
};
|
| 323 |
+
};
|
| 324 |
+
};
|
| 325 |
+
buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
|
| 326 |
+
compatibilityVersion = "Xcode 12.0";
|
| 327 |
+
developmentRegion = en;
|
| 328 |
+
hasScannedForEncodings = 0;
|
| 329 |
+
knownRegions = (
|
| 330 |
+
en,
|
| 331 |
+
Base,
|
| 332 |
+
);
|
| 333 |
+
mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
|
| 334 |
+
productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
|
| 335 |
+
projectDirPath = "";
|
| 336 |
+
projectRoot = "";
|
| 337 |
+
targets = (
|
| 338 |
+
3333333333333333333333AA /* ${APP_NAME} */,
|
| 339 |
+
);
|
| 340 |
+
};
|
| 341 |
+
/* End PBXProject section */
|
| 342 |
+
EOF
|
| 343 |
+
|
| 344 |
+
# Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS and tvOS settings
|
| 345 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 346 |
+
/* Begin PBXResourcesBuildPhase section */
|
| 347 |
+
6666666666666666666666AA /* Resources */ = {
|
| 348 |
+
isa = PBXResourcesBuildPhase;
|
| 349 |
+
buildActionMask = 2147483647;
|
| 350 |
+
files = (
|
| 351 |
+
);
|
| 352 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 353 |
+
};
|
| 354 |
+
/* End PBXResourcesBuildPhase section */
|
| 355 |
+
|
| 356 |
+
/* Begin PBXSourcesBuildPhase section */
|
| 357 |
+
5555555555555555555555AA /* Sources */ = {
|
| 358 |
+
isa = PBXSourcesBuildPhase;
|
| 359 |
+
buildActionMask = 2147483647;
|
| 360 |
+
files = (
|
| 361 |
+
33333333333333333333333 /* ContentView.swift in Sources */,
|
| 362 |
+
11111111111111111111111 /* App.swift in Sources */,
|
| 363 |
+
);
|
| 364 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 365 |
+
};
|
| 366 |
+
/* End PBXSourcesBuildPhase section */
|
| 367 |
+
|
| 368 |
+
/* Begin XCBuildConfiguration section */
|
| 369 |
+
9999999999999999999999AA /* Debug */ = {
|
| 370 |
+
isa = XCBuildConfiguration;
|
| 371 |
+
buildSettings = {
|
| 372 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 373 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 374 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 375 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 376 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 377 |
+
CLANG_ENABLE_MODULES = YES;
|
| 378 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 379 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 380 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 381 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 382 |
+
CLANG_WARN_COMMA = YES;
|
| 383 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 384 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 385 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 386 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 387 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 388 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 389 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 390 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 391 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 392 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 393 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 394 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 395 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 396 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 397 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 398 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 399 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 400 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 401 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 402 |
+
COPY_PHASE_STRIP = NO;
|
| 403 |
+
DEBUG_INFORMATION_FORMAT = dwarf;
|
| 404 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 405 |
+
ENABLE_TESTABILITY = YES;
|
| 406 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 407 |
+
GCC_DYNAMIC_NO_PIC = NO;
|
| 408 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 409 |
+
GCC_OPTIMIZATION_LEVEL = 0;
|
| 410 |
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
| 411 |
+
"DEBUG=1",
|
| 412 |
+
"$(inherited)",
|
| 413 |
+
);
|
| 414 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 415 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 416 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 417 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 418 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 419 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 420 |
+
TVOS_DEPLOYMENT_TARGET = 15.0;
|
| 421 |
+
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
| 422 |
+
MTL_FAST_MATH = YES;
|
| 423 |
+
ONLY_ACTIVE_ARCH = YES;
|
| 424 |
+
SDKROOT = appletvos;
|
| 425 |
+
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
| 426 |
+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
| 427 |
+
};
|
| 428 |
+
name = Debug;
|
| 429 |
+
};
|
| 430 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
|
| 431 |
+
isa = XCBuildConfiguration;
|
| 432 |
+
buildSettings = {
|
| 433 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 434 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 435 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 436 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 437 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 438 |
+
CLANG_ENABLE_MODULES = YES;
|
| 439 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 440 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 441 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 442 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 443 |
+
CLANG_WARN_COMMA = YES;
|
| 444 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 445 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 446 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 447 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 448 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 449 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 450 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 451 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 452 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 453 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 454 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 455 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 456 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 457 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 458 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 459 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 460 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 461 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 462 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 463 |
+
COPY_PHASE_STRIP = NO;
|
| 464 |
+
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
| 465 |
+
ENABLE_NS_ASSERTIONS = NO;
|
| 466 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 467 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 468 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 469 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 470 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 471 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 472 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 473 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 474 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 475 |
+
TVOS_DEPLOYMENT_TARGET = 15.0;
|
| 476 |
+
MTL_ENABLE_DEBUG_INFO = NO;
|
| 477 |
+
MTL_FAST_MATH = YES;
|
| 478 |
+
SDKROOT = appletvos;
|
| 479 |
+
SWIFT_COMPILATION_MODE = wholemodule;
|
| 480 |
+
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
| 481 |
+
VALIDATE_PRODUCT = YES;
|
| 482 |
+
};
|
| 483 |
+
name = Release;
|
| 484 |
+
};
|
| 485 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
|
| 486 |
+
isa = XCBuildConfiguration;
|
| 487 |
+
buildSettings = {
|
| 488 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 489 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 490 |
+
CODE_SIGN_STYLE = Manual;
|
| 491 |
+
DEVELOPMENT_TEAM = "";
|
| 492 |
+
ENABLE_PREVIEWS = YES;
|
| 493 |
+
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
| 494 |
+
INFOPLIST_FILE = "TVOSLlamaTest/Info.plist";
|
| 495 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 496 |
+
"$(inherited)",
|
| 497 |
+
"@executable_path/Frameworks",
|
| 498 |
+
);
|
| 499 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.TVOSLlamaTest";
|
| 500 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 501 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 502 |
+
SWIFT_VERSION = 5.0;
|
| 503 |
+
TARGETED_DEVICE_FAMILY = 3;
|
| 504 |
+
};
|
| 505 |
+
name = Debug;
|
| 506 |
+
};
|
| 507 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
|
| 508 |
+
isa = XCBuildConfiguration;
|
| 509 |
+
buildSettings = {
|
| 510 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 511 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 512 |
+
CODE_SIGN_STYLE = Manual;
|
| 513 |
+
DEVELOPMENT_TEAM = "";
|
| 514 |
+
ENABLE_PREVIEWS = YES;
|
| 515 |
+
FRAMEWORK_SEARCH_PATHS = (
|
| 516 |
+
"$(inherited)",
|
| 517 |
+
"$(PROJECT_DIR)",
|
| 518 |
+
);
|
| 519 |
+
INFOPLIST_FILE = "TVOSLlamaTest/Info.plist";
|
| 520 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 521 |
+
"$(inherited)",
|
| 522 |
+
"@executable_path/Frameworks",
|
| 523 |
+
);
|
| 524 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.TVOSLlamaTest";
|
| 525 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 526 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 527 |
+
SWIFT_VERSION = 5.0;
|
| 528 |
+
TARGETED_DEVICE_FAMILY = 3;
|
| 529 |
+
};
|
| 530 |
+
name = Release;
|
| 531 |
+
};
|
| 532 |
+
/* End XCBuildConfiguration section */
|
| 533 |
+
EOF
|
| 534 |
+
|
| 535 |
+
# Finish the project.pbxproj file
|
| 536 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 537 |
+
/* Begin XCConfigurationList section */
|
| 538 |
+
8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
|
| 539 |
+
isa = XCConfigurationList;
|
| 540 |
+
buildConfigurations = (
|
| 541 |
+
9999999999999999999999AA /* Debug */,
|
| 542 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
|
| 543 |
+
);
|
| 544 |
+
defaultConfigurationIsVisible = 0;
|
| 545 |
+
defaultConfigurationName = Release;
|
| 546 |
+
};
|
| 547 |
+
4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
|
| 548 |
+
isa = XCConfigurationList;
|
| 549 |
+
buildConfigurations = (
|
| 550 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
|
| 551 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
|
| 552 |
+
);
|
| 553 |
+
defaultConfigurationIsVisible = 0;
|
| 554 |
+
defaultConfigurationName = Release;
|
| 555 |
+
};
|
| 556 |
+
/* End XCConfigurationList section */
|
| 557 |
+
};
|
| 558 |
+
rootObject = 7777777777777777777777AA /* Project object */;
|
| 559 |
+
}
|
| 560 |
+
EOF
|
| 561 |
+
|
| 562 |
+
# 2. Copy XCFramework to test project
|
| 563 |
+
echo "Copying XCFramework to test project..."
|
| 564 |
+
cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
|
| 565 |
+
|
| 566 |
+
# 3. Build and archive the app
|
| 567 |
+
echo "Building and archiving test app..."
|
| 568 |
+
cd "${TEMP_DIR}/${APP_NAME}"
|
| 569 |
+
|
| 570 |
+
# Create a simple xcscheme file to avoid xcodebuild scheme issues
|
| 571 |
+
mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
|
| 572 |
+
cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
|
| 573 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 574 |
+
<Scheme
|
| 575 |
+
LastUpgradeVersion = "1240"
|
| 576 |
+
version = "1.3">
|
| 577 |
+
<BuildAction
|
| 578 |
+
parallelizeBuildables = "YES"
|
| 579 |
+
buildImplicitDependencies = "YES">
|
| 580 |
+
<BuildActionEntries>
|
| 581 |
+
<BuildActionEntry
|
| 582 |
+
buildForTesting = "YES"
|
| 583 |
+
buildForRunning = "YES"
|
| 584 |
+
buildForProfiling = "YES"
|
| 585 |
+
buildForArchiving = "YES"
|
| 586 |
+
buildForAnalyzing = "YES">
|
| 587 |
+
<BuildableReference
|
| 588 |
+
BuildableIdentifier = "primary"
|
| 589 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 590 |
+
BuildableName = "${APP_NAME}.app"
|
| 591 |
+
BlueprintName = "${APP_NAME}"
|
| 592 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 593 |
+
</BuildableReference>
|
| 594 |
+
</BuildActionEntry>
|
| 595 |
+
</BuildActionEntries>
|
| 596 |
+
</BuildAction>
|
| 597 |
+
<TestAction
|
| 598 |
+
buildConfiguration = "Debug"
|
| 599 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 600 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 601 |
+
shouldUseLaunchSchemeArgsEnv = "YES">
|
| 602 |
+
<Testables>
|
| 603 |
+
</Testables>
|
| 604 |
+
</TestAction>
|
| 605 |
+
<LaunchAction
|
| 606 |
+
buildConfiguration = "Debug"
|
| 607 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 608 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 609 |
+
launchStyle = "0"
|
| 610 |
+
useCustomWorkingDirectory = "NO"
|
| 611 |
+
ignoresPersistentStateOnLaunch = "NO"
|
| 612 |
+
debugDocumentVersioning = "YES"
|
| 613 |
+
debugServiceExtension = "internal"
|
| 614 |
+
allowLocationSimulation = "YES">
|
| 615 |
+
<BuildableProductRunnable
|
| 616 |
+
runnableDebuggingMode = "0">
|
| 617 |
+
<BuildableReference
|
| 618 |
+
BuildableIdentifier = "primary"
|
| 619 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 620 |
+
BuildableName = "${APP_NAME}.app"
|
| 621 |
+
BlueprintName = "${APP_NAME}"
|
| 622 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 623 |
+
</BuildableReference>
|
| 624 |
+
</BuildableProductRunnable>
|
| 625 |
+
</LaunchAction>
|
| 626 |
+
<ProfileAction
|
| 627 |
+
buildConfiguration = "Release"
|
| 628 |
+
shouldUseLaunchSchemeArgsEnv = "YES"
|
| 629 |
+
savedToolIdentifier = ""
|
| 630 |
+
useCustomWorkingDirectory = "NO"
|
| 631 |
+
debugDocumentVersioning = "YES">
|
| 632 |
+
<BuildableProductRunnable
|
| 633 |
+
runnableDebuggingMode = "0">
|
| 634 |
+
<BuildableReference
|
| 635 |
+
BuildableIdentifier = "primary"
|
| 636 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 637 |
+
BuildableName = "${APP_NAME}.app"
|
| 638 |
+
BlueprintName = "${APP_NAME}"
|
| 639 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 640 |
+
</BuildableReference>
|
| 641 |
+
</BuildableProductRunnable>
|
| 642 |
+
</ProfileAction>
|
| 643 |
+
<AnalyzeAction
|
| 644 |
+
buildConfiguration = "Debug">
|
| 645 |
+
</AnalyzeAction>
|
| 646 |
+
<ArchiveAction
|
| 647 |
+
buildConfiguration = "Release"
|
| 648 |
+
revealArchiveInOrganizer = "YES">
|
| 649 |
+
</ArchiveAction>
|
| 650 |
+
</Scheme>
|
| 651 |
+
EOF
|
| 652 |
+
|
| 653 |
+
# Now use xcodebuild with an explicitly defined product name for tvOS
|
| 654 |
+
xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk appletvos -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
|
| 655 |
+
|
| 656 |
+
# 4. Create IPA from archive
|
| 657 |
+
echo "Creating IPA from archive..."
|
| 658 |
+
mkdir -p "${TEMP_DIR}/Payload"
|
| 659 |
+
cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${TEMP_DIR}/Payload/"
|
| 660 |
+
|
| 661 |
+
# Check and log app structure before zipping
|
| 662 |
+
echo "App structure:"
|
| 663 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/"
|
| 664 |
+
echo "Frameworks:"
|
| 665 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 666 |
+
|
| 667 |
+
cd "${TEMP_DIR}"
|
| 668 |
+
zip -r "${IPA_PATH}" Payload
|
| 669 |
+
|
| 670 |
+
# Check embedded provisioning profile
|
| 671 |
+
echo "Checking provisioning profile (if any)..."
|
| 672 |
+
PROVISIONING_PROFILE=$(find "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" -name "embedded.mobileprovision" 2>/dev/null)
|
| 673 |
+
if [ -n "$PROVISIONING_PROFILE" ]; then
|
| 674 |
+
echo "Found embedded provisioning profile:"
|
| 675 |
+
security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
|
| 676 |
+
else
|
| 677 |
+
echo "No embedded provisioning profile found (expected for ad-hoc builds)"
|
| 678 |
+
fi
|
| 679 |
+
|
| 680 |
+
# 5. Validate the IPA
|
| 681 |
+
echo "Validating IPA..."
|
| 682 |
+
VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
|
| 683 |
+
|
| 684 |
+
# Check if authentication credentials are provided
|
| 685 |
+
AUTH_ARGS=""
|
| 686 |
+
if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
|
| 687 |
+
echo "Using Apple ID authentication for validation..."
|
| 688 |
+
AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
|
| 689 |
+
else
|
| 690 |
+
echo "No authentication credentials provided. Will perform basic validation."
|
| 691 |
+
echo "To use your personal developer account, you can run the script with:"
|
| 692 |
+
echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-tvos.sh"
|
| 693 |
+
echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
|
| 694 |
+
fi
|
| 695 |
+
|
| 696 |
+
# Run validation with detailed output
|
| 697 |
+
echo "Running validation with altool..."
|
| 698 |
+
if [ -n "$AUTH_ARGS" ]; then
|
| 699 |
+
# Use eval to properly handle the quoted arguments
|
| 700 |
+
eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type tvos --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 701 |
+
else
|
| 702 |
+
xcrun altool --validate-app -f "${IPA_PATH}" --type tvos --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 703 |
+
fi
|
| 704 |
+
VALIDATION_RESULT=$?
|
| 705 |
+
|
| 706 |
+
# Final validation result
|
| 707 |
+
FINAL_VALIDATION_RESULT=0
|
| 708 |
+
|
| 709 |
+
# Check if validation failed because the app isn't in App Store Connect
|
| 710 |
+
if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then
|
| 711 |
+
echo "⚠️ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"
|
| 712 |
+
echo "This is expected for apps that haven't been registered in App Store Connect yet."
|
| 713 |
+
echo "This doesn't indicate a problem with the build or framework."
|
| 714 |
+
|
| 715 |
+
# Perform alternative validation
|
| 716 |
+
echo "Performing alternative validation checks..."
|
| 717 |
+
|
| 718 |
+
# Check if IPA was created successfully
|
| 719 |
+
if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then
|
| 720 |
+
echo "✅ IPA file created successfully"
|
| 721 |
+
else
|
| 722 |
+
echo "❌ IPA file not created or empty"
|
| 723 |
+
FINAL_VALIDATION_RESULT=1
|
| 724 |
+
fi
|
| 725 |
+
|
| 726 |
+
# Check if app binary exists and is executable
|
| 727 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then
|
| 728 |
+
echo "✅ App binary exists and is executable"
|
| 729 |
+
else
|
| 730 |
+
echo "❌ App binary missing or not executable"
|
| 731 |
+
FINAL_VALIDATION_RESULT=1
|
| 732 |
+
fi
|
| 733 |
+
|
| 734 |
+
# Check if framework was properly embedded
|
| 735 |
+
if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework" ]; then
|
| 736 |
+
echo "✅ llama.framework properly embedded"
|
| 737 |
+
else
|
| 738 |
+
echo "❌ llama.framework not properly embedded"
|
| 739 |
+
FINAL_VALIDATION_RESULT=1
|
| 740 |
+
fi
|
| 741 |
+
|
| 742 |
+
# Check if framework binary exists
|
| 743 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" ]; then
|
| 744 |
+
echo "✅ Framework binary exists"
|
| 745 |
+
|
| 746 |
+
# Further validate framework by checking architecture
|
| 747 |
+
ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" 2>/dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ')
|
| 748 |
+
if [ -n "$ARCHS" ]; then
|
| 749 |
+
echo "✅ Framework architecture(s): $ARCHS"
|
| 750 |
+
else
|
| 751 |
+
echo "⚠️ Could not determine framework architecture"
|
| 752 |
+
fi
|
| 753 |
+
else
|
| 754 |
+
echo "❌ Framework binary missing"
|
| 755 |
+
FINAL_VALIDATION_RESULT=1
|
| 756 |
+
fi
|
| 757 |
+
|
| 758 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 759 |
+
echo "✅ Alternative validation PASSED: App built successfully with embedded framework"
|
| 760 |
+
else
|
| 761 |
+
echo "❌ Alternative validation FAILED: Issues found with the app or framework"
|
| 762 |
+
fi
|
| 763 |
+
elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then
|
| 764 |
+
echo "✅ tvOS Validation PASSED: IPA successfully validated"
|
| 765 |
+
echo "Results saved to ${VALIDATION_OUTPUT}"
|
| 766 |
+
else
|
| 767 |
+
echo "❌ tvOS Validation FAILED: IPA validation found issues"
|
| 768 |
+
echo "See validation output at ${VALIDATION_OUTPUT}"
|
| 769 |
+
echo ""
|
| 770 |
+
echo "==== VALIDATION ERRORS ===="
|
| 771 |
+
|
| 772 |
+
# Try to extract specific errors from the output
|
| 773 |
+
if grep -q "Error" "${VALIDATION_OUTPUT}"; then
|
| 774 |
+
grep -A 5 "Error" "${VALIDATION_OUTPUT}"
|
| 775 |
+
else
|
| 776 |
+
# If no specific error found, show the whole log
|
| 777 |
+
cat "${VALIDATION_OUTPUT}"
|
| 778 |
+
fi
|
| 779 |
+
|
| 780 |
+
# Additional debugging: check IPA contents
|
| 781 |
+
echo ""
|
| 782 |
+
echo "==== IPA CONTENTS ===="
|
| 783 |
+
mkdir -p "${TEMP_DIR}/ipa_contents"
|
| 784 |
+
unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"
|
| 785 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"
|
| 786 |
+
|
| 787 |
+
# Check for code signing issues
|
| 788 |
+
echo ""
|
| 789 |
+
echo "==== CODE SIGNING INFO ===="
|
| 790 |
+
codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"
|
| 791 |
+
|
| 792 |
+
# Check embedded frameworks
|
| 793 |
+
echo ""
|
| 794 |
+
echo "==== FRAMEWORK INFO ===="
|
| 795 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 796 |
+
fi
|
| 797 |
+
|
| 798 |
+
# Don't clean up on error to allow inspection
|
| 799 |
+
if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
|
| 800 |
+
echo ""
|
| 801 |
+
echo "Temporary files kept for inspection at: ${TEMP_DIR}"
|
| 802 |
+
echo "===== tvOS Validation Process Failed ====="
|
| 803 |
+
exit 1
|
| 804 |
+
fi
|
| 805 |
+
|
| 806 |
+
# Clean up temporary files but keep build artifacts
|
| 807 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 808 |
+
echo "Cleaning up temporary files..."
|
| 809 |
+
#rm -rf "${TEMP_DIR}"
|
| 810 |
+
fi
|
| 811 |
+
|
| 812 |
+
echo "===== tvOS Validation Process Completed ====="
|
| 813 |
+
exit $FINAL_VALIDATION_RESULT
|
llama.cpp/scripts/apple/validate-visionos.sh
ADDED
|
@@ -0,0 +1,811 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
# validate-visionos.sh - Validate visionOS Application with embedded llama.xcframework using SwiftUI
|
| 3 |
+
|
| 4 |
+
# Authentication options (optional) (can be set via environment variables)
|
| 5 |
+
# To use: export APPLE_ID=your.email@example.com
|
| 6 |
+
# export APPLE_PASSWORD=your-app-specific-password
|
| 7 |
+
# ./validate-visionos.sh
|
| 8 |
+
APPLE_ID=${APPLE_ID:-""}
|
| 9 |
+
APPLE_PASSWORD=${APPLE_PASSWORD:-""}
|
| 10 |
+
|
| 11 |
+
# Ensure the script exits on error
|
| 12 |
+
set -e
|
| 13 |
+
|
| 14 |
+
# Function to print usage instructions
|
| 15 |
+
print_usage() {
|
| 16 |
+
echo "Usage: ./validate-visionos.sh [OPTIONS]"
|
| 17 |
+
echo ""
|
| 18 |
+
echo "Options:"
|
| 19 |
+
echo " --help Show this help message"
|
| 20 |
+
echo " --apple-id EMAIL Apple ID email for validation"
|
| 21 |
+
echo " --apple-password PWD App-specific password for Apple ID"
|
| 22 |
+
echo ""
|
| 23 |
+
echo "Environment variables:"
|
| 24 |
+
echo " APPLE_ID Apple ID email for validation"
|
| 25 |
+
echo " APPLE_PASSWORD App-specific password for Apple ID"
|
| 26 |
+
echo ""
|
| 27 |
+
echo "Notes:"
|
| 28 |
+
echo " - Command line options take precedence over environment variables"
|
| 29 |
+
echo " - Authentication is optional. If not provided, alternative validation will be performed"
|
| 30 |
+
echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
# Parse command line arguments
|
| 34 |
+
while [[ $# -gt 0 ]]; do
|
| 35 |
+
case $1 in
|
| 36 |
+
--help)
|
| 37 |
+
print_usage
|
| 38 |
+
exit 0
|
| 39 |
+
;;
|
| 40 |
+
--apple-id)
|
| 41 |
+
APPLE_ID="$2"
|
| 42 |
+
shift 2
|
| 43 |
+
;;
|
| 44 |
+
--apple-password)
|
| 45 |
+
APPLE_PASSWORD="$2"
|
| 46 |
+
shift 2
|
| 47 |
+
;;
|
| 48 |
+
*)
|
| 49 |
+
echo "Unknown option: $1"
|
| 50 |
+
print_usage
|
| 51 |
+
exit 1
|
| 52 |
+
;;
|
| 53 |
+
esac
|
| 54 |
+
done
|
| 55 |
+
|
| 56 |
+
# Function to clean up in case of error
|
| 57 |
+
cleanup() {
|
| 58 |
+
# Don't clean up temp files on error to help with debugging
|
| 59 |
+
echo "===== visionOS Validation Process Failed ====="
|
| 60 |
+
exit 1
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
# Set up trap to call cleanup function on error
|
| 64 |
+
trap cleanup ERR
|
| 65 |
+
|
| 66 |
+
set -e # Exit on any error
|
| 67 |
+
|
| 68 |
+
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
|
| 69 |
+
BUILD_DIR="${ROOT_DIR}/validation-builds/visionos"
|
| 70 |
+
|
| 71 |
+
# Configuration
|
| 72 |
+
APP_NAME="VisionOSLlamaTest"
|
| 73 |
+
BUNDLE_ID="org.ggml.VisionOSLlamaTest"
|
| 74 |
+
XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/llama.xcframework"
|
| 75 |
+
TEMP_DIR="${BUILD_DIR}/temp"
|
| 76 |
+
ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
|
| 77 |
+
IPA_PATH="${BUILD_DIR}/${APP_NAME}.ipa"
|
| 78 |
+
VALIDATION_DIR="${BUILD_DIR}/validation"
|
| 79 |
+
|
| 80 |
+
# Create necessary directories
|
| 81 |
+
mkdir -p "${BUILD_DIR}"
|
| 82 |
+
mkdir -p "${TEMP_DIR}"
|
| 83 |
+
mkdir -p "${VALIDATION_DIR}"
|
| 84 |
+
|
| 85 |
+
echo "===== visionOS Validation Process Started ====="
|
| 86 |
+
|
| 87 |
+
# 1. Create a simple test app project
|
| 88 |
+
echo "Creating test visionOS app project..."
|
| 89 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
|
| 90 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
|
| 91 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 92 |
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
| 93 |
+
<plist version="1.0">
|
| 94 |
+
<dict>
|
| 95 |
+
<key>CFBundleDevelopmentRegion</key>
|
| 96 |
+
<string>en</string>
|
| 97 |
+
<key>CFBundleExecutable</key>
|
| 98 |
+
<string>${APP_NAME}</string>
|
| 99 |
+
<key>CFBundleIdentifier</key>
|
| 100 |
+
<string>${BUNDLE_ID}</string>
|
| 101 |
+
<key>CFBundleInfoDictionaryVersion</key>
|
| 102 |
+
<string>6.0</string>
|
| 103 |
+
<key>CFBundleName</key>
|
| 104 |
+
<string>${APP_NAME}</string>
|
| 105 |
+
<key>CFBundlePackageType</key>
|
| 106 |
+
<string>APPL</string>
|
| 107 |
+
<key>CFBundleShortVersionString</key>
|
| 108 |
+
<string>1.0</string>
|
| 109 |
+
<key>CFBundleVersion</key>
|
| 110 |
+
<string>1</string>
|
| 111 |
+
</dict>
|
| 112 |
+
</plist>
|
| 113 |
+
EOF
|
| 114 |
+
|
| 115 |
+
# Create SwiftUI app files
|
| 116 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
|
| 117 |
+
|
| 118 |
+
# Create App.swift
|
| 119 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
|
| 120 |
+
import SwiftUI
|
| 121 |
+
import llama
|
| 122 |
+
|
| 123 |
+
@main
|
| 124 |
+
struct LlamaTestApp: App {
|
| 125 |
+
var body: some Scene {
|
| 126 |
+
WindowGroup {
|
| 127 |
+
ContentView()
|
| 128 |
+
}
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
EOF
|
| 132 |
+
|
| 133 |
+
# Create ContentView.swift with visionOS specific elements
|
| 134 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
|
| 135 |
+
import SwiftUI
|
| 136 |
+
import llama
|
| 137 |
+
|
| 138 |
+
struct ContentView: View {
|
| 139 |
+
// Test that we can initialize a llama context params struct
|
| 140 |
+
let params = llama_context_default_params()
|
| 141 |
+
|
| 142 |
+
var body: some View {
|
| 143 |
+
VStack(spacing: 20) {
|
| 144 |
+
Text("Llama Framework Test on visionOS")
|
| 145 |
+
.font(.largeTitle)
|
| 146 |
+
.padding()
|
| 147 |
+
|
| 148 |
+
Text("llama_context_default_params() created successfully")
|
| 149 |
+
.font(.headline)
|
| 150 |
+
.multilineTextAlignment(.center)
|
| 151 |
+
.padding()
|
| 152 |
+
|
| 153 |
+
// Display some param values to confirm the framework is working
|
| 154 |
+
Text("n_ctx: \(params.n_ctx)")
|
| 155 |
+
.font(.body)
|
| 156 |
+
|
| 157 |
+
Text("n_batch: \(params.n_batch)")
|
| 158 |
+
.font(.body)
|
| 159 |
+
|
| 160 |
+
Spacer()
|
| 161 |
+
}
|
| 162 |
+
.padding()
|
| 163 |
+
.frame(width: 500, height: 400)
|
| 164 |
+
}
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
struct ContentView_Previews: PreviewProvider {
|
| 168 |
+
static var previews: some View {
|
| 169 |
+
ContentView()
|
| 170 |
+
}
|
| 171 |
+
}
|
| 172 |
+
EOF
|
| 173 |
+
|
| 174 |
+
# Create project.pbxproj, fixing the framework search paths issues
|
| 175 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
|
| 176 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 177 |
+
// !$*UTF8*$!
|
| 178 |
+
{
|
| 179 |
+
archiveVersion = 1;
|
| 180 |
+
classes = {
|
| 181 |
+
};
|
| 182 |
+
objectVersion = 54;
|
| 183 |
+
objects = {
|
| 184 |
+
|
| 185 |
+
/* Begin PBXBuildFile section */
|
| 186 |
+
11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
|
| 187 |
+
33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
|
| 188 |
+
55555555555555555555555 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 189 |
+
77777777777777777777777 /* llama.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 190 |
+
/* End PBXBuildFile section */
|
| 191 |
+
|
| 192 |
+
/* Begin PBXCopyFilesBuildPhase section */
|
| 193 |
+
88888888888888888888888 /* Embed Frameworks */ = {
|
| 194 |
+
isa = PBXCopyFilesBuildPhase;
|
| 195 |
+
buildActionMask = 2147483647;
|
| 196 |
+
dstPath = "";
|
| 197 |
+
dstSubfolderSpec = 10;
|
| 198 |
+
files = (
|
| 199 |
+
77777777777777777777777 /* llama.xcframework in Embed Frameworks */,
|
| 200 |
+
);
|
| 201 |
+
name = "Embed Frameworks";
|
| 202 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 203 |
+
};
|
| 204 |
+
/* End PBXCopyFilesBuildPhase section */
|
| 205 |
+
|
| 206 |
+
/* Begin PBXFileReference section */
|
| 207 |
+
EOF
|
| 208 |
+
|
| 209 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 210 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 211 |
+
99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 212 |
+
22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
|
| 213 |
+
44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
| 214 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
| 215 |
+
66666666666666666666666 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; };
|
| 216 |
+
/* End PBXFileReference section */
|
| 217 |
+
EOF
|
| 218 |
+
|
| 219 |
+
# Add the rest of the project file with fixed framework search paths
|
| 220 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 221 |
+
/* Begin PBXFrameworksBuildPhase section */
|
| 222 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
|
| 223 |
+
isa = PBXFrameworksBuildPhase;
|
| 224 |
+
buildActionMask = 2147483647;
|
| 225 |
+
files = (
|
| 226 |
+
55555555555555555555555 /* llama.xcframework in Frameworks */,
|
| 227 |
+
);
|
| 228 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 229 |
+
};
|
| 230 |
+
/* End PBXFrameworksBuildPhase section */
|
| 231 |
+
|
| 232 |
+
/* Begin PBXGroup section */
|
| 233 |
+
EOF
|
| 234 |
+
|
| 235 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 236 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 237 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
|
| 238 |
+
isa = PBXGroup;
|
| 239 |
+
children = (
|
| 240 |
+
99999999999999999999999 /* ${APP_NAME}.app */,
|
| 241 |
+
);
|
| 242 |
+
name = Products;
|
| 243 |
+
sourceTree = "<group>";
|
| 244 |
+
};
|
| 245 |
+
EOF
|
| 246 |
+
|
| 247 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 248 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
|
| 249 |
+
isa = PBXGroup;
|
| 250 |
+
children = (
|
| 251 |
+
66666666666666666666666 /* llama.xcframework */,
|
| 252 |
+
);
|
| 253 |
+
name = Frameworks;
|
| 254 |
+
sourceTree = "<group>";
|
| 255 |
+
};
|
| 256 |
+
EEEEEEEEEEEEEEEEEEEEEEEE = {
|
| 257 |
+
isa = PBXGroup;
|
| 258 |
+
children = (
|
| 259 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* VisionOSLlamaTest */,
|
| 260 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
|
| 261 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
|
| 262 |
+
);
|
| 263 |
+
sourceTree = "<group>";
|
| 264 |
+
};
|
| 265 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* VisionOSLlamaTest */ = {
|
| 266 |
+
isa = PBXGroup;
|
| 267 |
+
children = (
|
| 268 |
+
1111111111111111111111AA /* Sources */,
|
| 269 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
|
| 270 |
+
);
|
| 271 |
+
path = "VisionOSLlamaTest";
|
| 272 |
+
sourceTree = "<group>";
|
| 273 |
+
};
|
| 274 |
+
1111111111111111111111AA /* Sources */ = {
|
| 275 |
+
isa = PBXGroup;
|
| 276 |
+
children = (
|
| 277 |
+
22222222222222222222222 /* App.swift */,
|
| 278 |
+
44444444444444444444444 /* ContentView.swift */,
|
| 279 |
+
);
|
| 280 |
+
path = Sources;
|
| 281 |
+
sourceTree = "<group>";
|
| 282 |
+
};
|
| 283 |
+
/* End PBXGroup section */
|
| 284 |
+
EOF
|
| 285 |
+
|
| 286 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 287 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 288 |
+
/* Begin PBXNativeTarget section */
|
| 289 |
+
3333333333333333333333AA /* ${APP_NAME} */ = {
|
| 290 |
+
isa = PBXNativeTarget;
|
| 291 |
+
buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
|
| 292 |
+
buildPhases = (
|
| 293 |
+
5555555555555555555555AA /* Sources */,
|
| 294 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
|
| 295 |
+
6666666666666666666666AA /* Resources */,
|
| 296 |
+
88888888888888888888888 /* Embed Frameworks */,
|
| 297 |
+
);
|
| 298 |
+
buildRules = (
|
| 299 |
+
);
|
| 300 |
+
dependencies = (
|
| 301 |
+
);
|
| 302 |
+
name = "${APP_NAME}";
|
| 303 |
+
productName = "${APP_NAME}";
|
| 304 |
+
productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
|
| 305 |
+
productType = "com.apple.product-type.application";
|
| 306 |
+
};
|
| 307 |
+
/* End PBXNativeTarget section */
|
| 308 |
+
|
| 309 |
+
/* Begin PBXProject section */
|
| 310 |
+
7777777777777777777777AA /* Project object */ = {
|
| 311 |
+
isa = PBXProject;
|
| 312 |
+
attributes = {
|
| 313 |
+
LastSwiftUpdateCheck = 1510;
|
| 314 |
+
LastUpgradeCheck = 1510;
|
| 315 |
+
TargetAttributes = {
|
| 316 |
+
3333333333333333333333AA = {
|
| 317 |
+
CreatedOnToolsVersion = 15.1;
|
| 318 |
+
};
|
| 319 |
+
};
|
| 320 |
+
};
|
| 321 |
+
buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
|
| 322 |
+
compatibilityVersion = "Xcode 15.0";
|
| 323 |
+
developmentRegion = en;
|
| 324 |
+
hasScannedForEncodings = 0;
|
| 325 |
+
knownRegions = (
|
| 326 |
+
en,
|
| 327 |
+
Base,
|
| 328 |
+
);
|
| 329 |
+
mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
|
| 330 |
+
productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
|
| 331 |
+
projectDirPath = "";
|
| 332 |
+
projectRoot = "";
|
| 333 |
+
targets = (
|
| 334 |
+
3333333333333333333333AA /* ${APP_NAME} */,
|
| 335 |
+
);
|
| 336 |
+
};
|
| 337 |
+
/* End PBXProject section */
|
| 338 |
+
EOF
|
| 339 |
+
|
| 340 |
+
# Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS
|
| 341 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 342 |
+
/* Begin PBXResourcesBuildPhase section */
|
| 343 |
+
6666666666666666666666AA /* Resources */ = {
|
| 344 |
+
isa = PBXResourcesBuildPhase;
|
| 345 |
+
buildActionMask = 2147483647;
|
| 346 |
+
files = (
|
| 347 |
+
);
|
| 348 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 349 |
+
};
|
| 350 |
+
/* End PBXResourcesBuildPhase section */
|
| 351 |
+
|
| 352 |
+
/* Begin PBXSourcesBuildPhase section */
|
| 353 |
+
5555555555555555555555AA /* Sources */ = {
|
| 354 |
+
isa = PBXSourcesBuildPhase;
|
| 355 |
+
buildActionMask = 2147483647;
|
| 356 |
+
files = (
|
| 357 |
+
33333333333333333333333 /* ContentView.swift in Sources */,
|
| 358 |
+
11111111111111111111111 /* App.swift in Sources */,
|
| 359 |
+
);
|
| 360 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 361 |
+
};
|
| 362 |
+
/* End PBXSourcesBuildPhase section */
|
| 363 |
+
|
| 364 |
+
/* Begin XCBuildConfiguration section */
|
| 365 |
+
9999999999999999999999AA /* Debug */ = {
|
| 366 |
+
isa = XCBuildConfiguration;
|
| 367 |
+
buildSettings = {
|
| 368 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 369 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 370 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 371 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 372 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 373 |
+
CLANG_ENABLE_MODULES = YES;
|
| 374 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 375 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 376 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 377 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 378 |
+
CLANG_WARN_COMMA = YES;
|
| 379 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 380 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 381 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 382 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 383 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 384 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 385 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 386 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 387 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 388 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 389 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 390 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 391 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 392 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 393 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 394 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 395 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 396 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 397 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 398 |
+
COPY_PHASE_STRIP = NO;
|
| 399 |
+
DEBUG_INFORMATION_FORMAT = dwarf;
|
| 400 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 401 |
+
ENABLE_TESTABILITY = YES;
|
| 402 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 403 |
+
GCC_DYNAMIC_NO_PIC = NO;
|
| 404 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 405 |
+
GCC_OPTIMIZATION_LEVEL = 0;
|
| 406 |
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
| 407 |
+
"DEBUG=1",
|
| 408 |
+
"$(inherited)",
|
| 409 |
+
);
|
| 410 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 411 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 412 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 413 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 414 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 415 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 416 |
+
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
| 417 |
+
MTL_FAST_MATH = YES;
|
| 418 |
+
ONLY_ACTIVE_ARCH = YES;
|
| 419 |
+
SDKROOT = xros;
|
| 420 |
+
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
| 421 |
+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
| 422 |
+
XROS_DEPLOYMENT_TARGET = 1.0;
|
| 423 |
+
};
|
| 424 |
+
name = Debug;
|
| 425 |
+
};
|
| 426 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
|
| 427 |
+
isa = XCBuildConfiguration;
|
| 428 |
+
buildSettings = {
|
| 429 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 430 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 431 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 432 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 433 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 434 |
+
CLANG_ENABLE_MODULES = YES;
|
| 435 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 436 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 437 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 438 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 439 |
+
CLANG_WARN_COMMA = YES;
|
| 440 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 441 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 442 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 443 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 444 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 445 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 446 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 447 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 448 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 449 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 450 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 451 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 452 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 453 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 454 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 455 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 456 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 457 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 458 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 459 |
+
COPY_PHASE_STRIP = NO;
|
| 460 |
+
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
| 461 |
+
ENABLE_NS_ASSERTIONS = NO;
|
| 462 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 463 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 464 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 465 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 466 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 467 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 468 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 469 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 470 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 471 |
+
MTL_ENABLE_DEBUG_INFO = NO;
|
| 472 |
+
MTL_FAST_MATH = YES;
|
| 473 |
+
SDKROOT = xros;
|
| 474 |
+
SWIFT_COMPILATION_MODE = wholemodule;
|
| 475 |
+
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
| 476 |
+
VALIDATE_PRODUCT = YES;
|
| 477 |
+
XROS_DEPLOYMENT_TARGET = 1.0;
|
| 478 |
+
};
|
| 479 |
+
name = Release;
|
| 480 |
+
};
|
| 481 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
|
| 482 |
+
isa = XCBuildConfiguration;
|
| 483 |
+
buildSettings = {
|
| 484 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 485 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 486 |
+
CODE_SIGN_STYLE = Manual;
|
| 487 |
+
DEVELOPMENT_TEAM = "";
|
| 488 |
+
ENABLE_PREVIEWS = YES;
|
| 489 |
+
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
| 490 |
+
INFOPLIST_FILE = "VisionOSLlamaTest/Info.plist";
|
| 491 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 492 |
+
"$(inherited)",
|
| 493 |
+
"@executable_path/Frameworks",
|
| 494 |
+
);
|
| 495 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.VisionOSLlamaTest";
|
| 496 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 497 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 498 |
+
SUPPORTED_PLATFORMS = "xros xrsimulator";
|
| 499 |
+
SWIFT_VERSION = 5.0;
|
| 500 |
+
TARGETED_DEVICE_FAMILY = "1,2,7";
|
| 501 |
+
};
|
| 502 |
+
name = Debug;
|
| 503 |
+
};
|
| 504 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
|
| 505 |
+
isa = XCBuildConfiguration;
|
| 506 |
+
buildSettings = {
|
| 507 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 508 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 509 |
+
CODE_SIGN_STYLE = Manual;
|
| 510 |
+
DEVELOPMENT_TEAM = "";
|
| 511 |
+
ENABLE_PREVIEWS = YES;
|
| 512 |
+
FRAMEWORK_SEARCH_PATHS = (
|
| 513 |
+
"$(inherited)",
|
| 514 |
+
"$(PROJECT_DIR)",
|
| 515 |
+
);
|
| 516 |
+
INFOPLIST_FILE = "VisionOSLlamaTest/Info.plist";
|
| 517 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 518 |
+
"$(inherited)",
|
| 519 |
+
"@executable_path/Frameworks",
|
| 520 |
+
);
|
| 521 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.VisionOSLlamaTest";
|
| 522 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 523 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 524 |
+
SUPPORTED_PLATFORMS = "xros xrsimulator";
|
| 525 |
+
SWIFT_VERSION = 5.0;
|
| 526 |
+
TARGETED_DEVICE_FAMILY = "1,2,7";
|
| 527 |
+
};
|
| 528 |
+
name = Release;
|
| 529 |
+
};
|
| 530 |
+
/* End XCBuildConfiguration section */
|
| 531 |
+
EOF
|
| 532 |
+
|
| 533 |
+
# Finish the project.pbxproj file
|
| 534 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 535 |
+
/* Begin XCConfigurationList section */
|
| 536 |
+
8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
|
| 537 |
+
isa = XCConfigurationList;
|
| 538 |
+
buildConfigurations = (
|
| 539 |
+
9999999999999999999999AA /* Debug */,
|
| 540 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
|
| 541 |
+
);
|
| 542 |
+
defaultConfigurationIsVisible = 0;
|
| 543 |
+
defaultConfigurationName = Release;
|
| 544 |
+
};
|
| 545 |
+
4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
|
| 546 |
+
isa = XCConfigurationList;
|
| 547 |
+
buildConfigurations = (
|
| 548 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
|
| 549 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
|
| 550 |
+
);
|
| 551 |
+
defaultConfigurationIsVisible = 0;
|
| 552 |
+
defaultConfigurationName = Release;
|
| 553 |
+
};
|
| 554 |
+
/* End XCConfigurationList section */
|
| 555 |
+
};
|
| 556 |
+
rootObject = 7777777777777777777777AA /* Project object */;
|
| 557 |
+
}
|
| 558 |
+
EOF
|
| 559 |
+
|
| 560 |
+
# 2. Copy XCFramework to test project
|
| 561 |
+
echo "Copying XCFramework to test project..."
|
| 562 |
+
cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
|
| 563 |
+
|
| 564 |
+
# 3. Build and archive the app
|
| 565 |
+
echo "Building and archiving test app..."
|
| 566 |
+
cd "${TEMP_DIR}/${APP_NAME}"
|
| 567 |
+
|
| 568 |
+
# Create a simple xcscheme file to avoid xcodebuild scheme issues
|
| 569 |
+
mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
|
| 570 |
+
cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
|
| 571 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 572 |
+
<Scheme
|
| 573 |
+
LastUpgradeVersion = "1510"
|
| 574 |
+
version = "1.3">
|
| 575 |
+
<BuildAction
|
| 576 |
+
parallelizeBuildables = "YES"
|
| 577 |
+
buildImplicitDependencies = "YES">
|
| 578 |
+
<BuildActionEntries>
|
| 579 |
+
<BuildActionEntry
|
| 580 |
+
buildForTesting = "YES"
|
| 581 |
+
buildForRunning = "YES"
|
| 582 |
+
buildForProfiling = "YES"
|
| 583 |
+
buildForArchiving = "YES"
|
| 584 |
+
buildForAnalyzing = "YES">
|
| 585 |
+
<BuildableReference
|
| 586 |
+
BuildableIdentifier = "primary"
|
| 587 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 588 |
+
BuildableName = "${APP_NAME}.app"
|
| 589 |
+
BlueprintName = "${APP_NAME}"
|
| 590 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 591 |
+
</BuildableReference>
|
| 592 |
+
</BuildActionEntry>
|
| 593 |
+
</BuildActionEntries>
|
| 594 |
+
</BuildAction>
|
| 595 |
+
<TestAction
|
| 596 |
+
buildConfiguration = "Debug"
|
| 597 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 598 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 599 |
+
shouldUseLaunchSchemeArgsEnv = "YES">
|
| 600 |
+
<Testables>
|
| 601 |
+
</Testables>
|
| 602 |
+
</TestAction>
|
| 603 |
+
<LaunchAction
|
| 604 |
+
buildConfiguration = "Debug"
|
| 605 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 606 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 607 |
+
launchStyle = "0"
|
| 608 |
+
useCustomWorkingDirectory = "NO"
|
| 609 |
+
ignoresPersistentStateOnLaunch = "NO"
|
| 610 |
+
debugDocumentVersioning = "YES"
|
| 611 |
+
debugServiceExtension = "internal"
|
| 612 |
+
allowLocationSimulation = "YES">
|
| 613 |
+
<BuildableProductRunnable
|
| 614 |
+
runnableDebuggingMode = "0">
|
| 615 |
+
<BuildableReference
|
| 616 |
+
BuildableIdentifier = "primary"
|
| 617 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 618 |
+
BuildableName = "${APP_NAME}.app"
|
| 619 |
+
BlueprintName = "${APP_NAME}"
|
| 620 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 621 |
+
</BuildableReference>
|
| 622 |
+
</BuildableProductRunnable>
|
| 623 |
+
</LaunchAction>
|
| 624 |
+
<ProfileAction
|
| 625 |
+
buildConfiguration = "Release"
|
| 626 |
+
shouldUseLaunchSchemeArgsEnv = "YES"
|
| 627 |
+
savedToolIdentifier = ""
|
| 628 |
+
useCustomWorkingDirectory = "NO"
|
| 629 |
+
debugDocumentVersioning = "YES">
|
| 630 |
+
<BuildableProductRunnable
|
| 631 |
+
runnableDebuggingMode = "0">
|
| 632 |
+
<BuildableReference
|
| 633 |
+
BuildableIdentifier = "primary"
|
| 634 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 635 |
+
BuildableName = "${APP_NAME}.app"
|
| 636 |
+
BlueprintName = "${APP_NAME}"
|
| 637 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 638 |
+
</BuildableReference>
|
| 639 |
+
</BuildableProductRunnable>
|
| 640 |
+
</ProfileAction>
|
| 641 |
+
<AnalyzeAction
|
| 642 |
+
buildConfiguration = "Debug">
|
| 643 |
+
</AnalyzeAction>
|
| 644 |
+
<ArchiveAction
|
| 645 |
+
buildConfiguration = "Release"
|
| 646 |
+
revealArchiveInOrganizer = "YES">
|
| 647 |
+
</ArchiveAction>
|
| 648 |
+
</Scheme>
|
| 649 |
+
EOF
|
| 650 |
+
|
| 651 |
+
# Now use xcodebuild with an explicitly defined product name for visionOS
|
| 652 |
+
xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk xros -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
|
| 653 |
+
|
| 654 |
+
# 4. Create IPA from archive
|
| 655 |
+
echo "Creating IPA from archive..."
|
| 656 |
+
mkdir -p "${TEMP_DIR}/Payload"
|
| 657 |
+
cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${TEMP_DIR}/Payload/"
|
| 658 |
+
|
| 659 |
+
# Check and log app structure before zipping
|
| 660 |
+
echo "App structure:"
|
| 661 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/"
|
| 662 |
+
echo "Frameworks:"
|
| 663 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 664 |
+
|
| 665 |
+
cd "${TEMP_DIR}"
|
| 666 |
+
zip -r "${IPA_PATH}" Payload
|
| 667 |
+
|
| 668 |
+
# Check embedded provisioning profile
|
| 669 |
+
echo "Checking provisioning profile (if any)..."
|
| 670 |
+
PROVISIONING_PROFILE=$(find "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" -name "embedded.mobileprovision" 2>/dev/null)
|
| 671 |
+
if [ -n "$PROVISIONING_PROFILE" ]; then
|
| 672 |
+
echo "Found embedded provisioning profile:"
|
| 673 |
+
security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
|
| 674 |
+
else
|
| 675 |
+
echo "No embedded provisioning profile found (expected for ad-hoc builds)"
|
| 676 |
+
fi
|
| 677 |
+
|
| 678 |
+
# 5. Validate the IPA
|
| 679 |
+
echo "Validating IPA..."
|
| 680 |
+
VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
|
| 681 |
+
|
| 682 |
+
# Check if authentication credentials are provided
|
| 683 |
+
AUTH_ARGS=""
|
| 684 |
+
if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
|
| 685 |
+
echo "Using Apple ID authentication for validation..."
|
| 686 |
+
AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
|
| 687 |
+
else
|
| 688 |
+
echo "No authentication credentials provided. Will perform basic validation."
|
| 689 |
+
echo "To use your personal developer account, you can run the script with:"
|
| 690 |
+
echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-visionos.sh"
|
| 691 |
+
echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
|
| 692 |
+
fi
|
| 693 |
+
|
| 694 |
+
# Run validation with detailed output
|
| 695 |
+
echo "Running validation with altool..."
|
| 696 |
+
if [ -n "$AUTH_ARGS" ]; then
|
| 697 |
+
# Use eval to properly handle the quoted arguments
|
| 698 |
+
eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type visionos --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 699 |
+
else
|
| 700 |
+
xcrun altool --validate-app -f "${IPA_PATH}" --type visionos --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 701 |
+
fi
|
| 702 |
+
VALIDATION_RESULT=$?
|
| 703 |
+
|
| 704 |
+
# Final validation result
|
| 705 |
+
FINAL_VALIDATION_RESULT=0
|
| 706 |
+
|
| 707 |
+
# Check if validation failed because the app isn't in App Store Connect
|
| 708 |
+
if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then
|
| 709 |
+
echo "⚠️ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"
|
| 710 |
+
echo "This is expected for apps that haven't been registered in App Store Connect yet."
|
| 711 |
+
echo "This doesn't indicate a problem with the build or framework."
|
| 712 |
+
|
| 713 |
+
# Perform alternative validation
|
| 714 |
+
echo "Performing alternative validation checks..."
|
| 715 |
+
|
| 716 |
+
# Check if IPA was created successfully
|
| 717 |
+
if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then
|
| 718 |
+
echo "✅ IPA file created successfully"
|
| 719 |
+
else
|
| 720 |
+
echo "❌ IPA file not created or empty"
|
| 721 |
+
FINAL_VALIDATION_RESULT=1
|
| 722 |
+
fi
|
| 723 |
+
|
| 724 |
+
# Check if app binary exists and is executable
|
| 725 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then
|
| 726 |
+
echo "✅ App binary exists and is executable"
|
| 727 |
+
else
|
| 728 |
+
echo "❌ App binary missing or not executable"
|
| 729 |
+
FINAL_VALIDATION_RESULT=1
|
| 730 |
+
fi
|
| 731 |
+
|
| 732 |
+
# Check if framework was properly embedded
|
| 733 |
+
if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework" ]; then
|
| 734 |
+
echo "✅ llama.framework properly embedded"
|
| 735 |
+
else
|
| 736 |
+
echo "❌ llama.framework not properly embedded"
|
| 737 |
+
FINAL_VALIDATION_RESULT=1
|
| 738 |
+
fi
|
| 739 |
+
|
| 740 |
+
# Check if framework binary exists
|
| 741 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" ]; then
|
| 742 |
+
echo "✅ Framework binary exists"
|
| 743 |
+
|
| 744 |
+
# Further validate framework by checking architecture
|
| 745 |
+
ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" 2>/dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ')
|
| 746 |
+
if [ -n "$ARCHS" ]; then
|
| 747 |
+
echo "✅ Framework architecture(s): $ARCHS"
|
| 748 |
+
else
|
| 749 |
+
echo "⚠️ Could not determine framework architecture"
|
| 750 |
+
fi
|
| 751 |
+
else
|
| 752 |
+
echo "❌ Framework binary missing"
|
| 753 |
+
FINAL_VALIDATION_RESULT=1
|
| 754 |
+
fi
|
| 755 |
+
|
| 756 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 757 |
+
echo "✅ Alternative validation PASSED: App built successfully with embedded framework"
|
| 758 |
+
else
|
| 759 |
+
echo "❌ Alternative validation FAILED: Issues found with the app or framework"
|
| 760 |
+
fi
|
| 761 |
+
elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then
|
| 762 |
+
echo "✅ visionOS Validation PASSED: IPA successfully validated"
|
| 763 |
+
echo "Results saved to ${VALIDATION_OUTPUT}"
|
| 764 |
+
else
|
| 765 |
+
echo "❌ visionOS Validation FAILED: IPA validation found issues"
|
| 766 |
+
echo "See validation output at ${VALIDATION_OUTPUT}"
|
| 767 |
+
echo ""
|
| 768 |
+
echo "==== VALIDATION ERRORS ===="
|
| 769 |
+
|
| 770 |
+
# Try to extract specific errors from the output
|
| 771 |
+
if grep -q "Error" "${VALIDATION_OUTPUT}"; then
|
| 772 |
+
grep -A 5 "Error" "${VALIDATION_OUTPUT}"
|
| 773 |
+
else
|
| 774 |
+
# If no specific error found, show the whole log
|
| 775 |
+
cat "${VALIDATION_OUTPUT}"
|
| 776 |
+
fi
|
| 777 |
+
|
| 778 |
+
# Additional debugging: check IPA contents
|
| 779 |
+
echo ""
|
| 780 |
+
echo "==== IPA CONTENTS ===="
|
| 781 |
+
mkdir -p "${TEMP_DIR}/ipa_contents"
|
| 782 |
+
unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"
|
| 783 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"
|
| 784 |
+
|
| 785 |
+
# Check for code signing issues
|
| 786 |
+
echo ""
|
| 787 |
+
echo "==== CODE SIGNING INFO ===="
|
| 788 |
+
codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"
|
| 789 |
+
|
| 790 |
+
# Check embedded frameworks
|
| 791 |
+
echo ""
|
| 792 |
+
echo "==== FRAMEWORK INFO ===="
|
| 793 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 794 |
+
fi
|
| 795 |
+
|
| 796 |
+
# Don't clean up on error to allow inspection
|
| 797 |
+
if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
|
| 798 |
+
echo ""
|
| 799 |
+
echo "Temporary files kept for inspection at: ${TEMP_DIR}"
|
| 800 |
+
echo "===== visionOS Validation Process Failed ====="
|
| 801 |
+
exit 1
|
| 802 |
+
fi
|
| 803 |
+
|
| 804 |
+
# Clean up temporary files but keep build artifacts
|
| 805 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 806 |
+
echo "Cleaning up temporary files..."
|
| 807 |
+
#rm -rf "${TEMP_DIR}"
|
| 808 |
+
fi
|
| 809 |
+
|
| 810 |
+
echo "===== visionOS Validation Process Completed ====="
|
| 811 |
+
exit $FINAL_VALIDATION_RESULT
|
llama.cpp/scripts/jinja/jinja-tester.py
ADDED
|
@@ -0,0 +1,504 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
import sys
|
| 3 |
+
import json
|
| 4 |
+
import argparse
|
| 5 |
+
import jinja2.ext as jinja2_ext
|
| 6 |
+
from PySide6.QtWidgets import (
|
| 7 |
+
QApplication,
|
| 8 |
+
QMainWindow,
|
| 9 |
+
QWidget,
|
| 10 |
+
QVBoxLayout,
|
| 11 |
+
QHBoxLayout,
|
| 12 |
+
QLabel,
|
| 13 |
+
QPlainTextEdit,
|
| 14 |
+
QTextEdit,
|
| 15 |
+
QPushButton,
|
| 16 |
+
QFileDialog,
|
| 17 |
+
)
|
| 18 |
+
from PySide6.QtGui import QColor, QColorConstants, QTextCursor, QTextFormat
|
| 19 |
+
from PySide6.QtCore import Qt, QRect, QSize
|
| 20 |
+
from jinja2 import TemplateSyntaxError
|
| 21 |
+
from jinja2.sandbox import ImmutableSandboxedEnvironment
|
| 22 |
+
from datetime import datetime
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def format_template_content(template_content):
|
| 26 |
+
"""Format the Jinja template content using Jinja2's lexer."""
|
| 27 |
+
if not template_content.strip():
|
| 28 |
+
return template_content
|
| 29 |
+
|
| 30 |
+
env = ImmutableSandboxedEnvironment()
|
| 31 |
+
tc_rstrip = template_content.rstrip()
|
| 32 |
+
tokens = list(env.lex(tc_rstrip))
|
| 33 |
+
result = ""
|
| 34 |
+
indent_level = 0
|
| 35 |
+
i = 0
|
| 36 |
+
|
| 37 |
+
while i < len(tokens):
|
| 38 |
+
token = tokens[i]
|
| 39 |
+
_, token_type, token_value = token
|
| 40 |
+
|
| 41 |
+
if token_type == "block_begin":
|
| 42 |
+
block_start = i
|
| 43 |
+
# Collect all tokens for this block construct
|
| 44 |
+
construct_content = token_value
|
| 45 |
+
end_token_type = token_type.replace("_begin", "_end")
|
| 46 |
+
j = i + 1
|
| 47 |
+
while j < len(tokens) and tokens[j][1] != end_token_type:
|
| 48 |
+
construct_content += tokens[j][2]
|
| 49 |
+
j += 1
|
| 50 |
+
|
| 51 |
+
if j < len(tokens): # Found the end token
|
| 52 |
+
construct_content += tokens[j][2]
|
| 53 |
+
i = j # Skip to the end token
|
| 54 |
+
|
| 55 |
+
# Check for control structure keywords for indentation
|
| 56 |
+
stripped_content = construct_content.strip()
|
| 57 |
+
instr = block_start + 1
|
| 58 |
+
while tokens[instr][1] == "whitespace":
|
| 59 |
+
instr = instr + 1
|
| 60 |
+
|
| 61 |
+
instruction_token = tokens[instr][2]
|
| 62 |
+
start_control_tokens = ["if", "for", "macro", "call", "block"]
|
| 63 |
+
end_control_tokens = ["end" + t for t in start_control_tokens]
|
| 64 |
+
is_control_start = any(
|
| 65 |
+
instruction_token.startswith(kw) for kw in start_control_tokens
|
| 66 |
+
)
|
| 67 |
+
is_control_end = any(
|
| 68 |
+
instruction_token.startswith(kw) for kw in end_control_tokens
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
# Adjust indentation for control structures
|
| 72 |
+
# For control end blocks, decrease indent BEFORE adding the content
|
| 73 |
+
if is_control_end:
|
| 74 |
+
indent_level = max(0, indent_level - 1)
|
| 75 |
+
|
| 76 |
+
# Remove all previous whitespace before this block
|
| 77 |
+
result = result.rstrip()
|
| 78 |
+
|
| 79 |
+
# Add proper indent, but only if this is not the first token
|
| 80 |
+
added_newline = False
|
| 81 |
+
if result: # Only add newline and indent if there's already content
|
| 82 |
+
result += (
|
| 83 |
+
"\n" + " " * indent_level
|
| 84 |
+
) # Use 2 spaces per indent level
|
| 85 |
+
added_newline = True
|
| 86 |
+
else: # For the first token, don't add any indent
|
| 87 |
+
result += ""
|
| 88 |
+
|
| 89 |
+
# Add the block content
|
| 90 |
+
result += stripped_content
|
| 91 |
+
|
| 92 |
+
# Add '-' after '%' if it wasn't there and we added a newline or indent
|
| 93 |
+
if (
|
| 94 |
+
added_newline
|
| 95 |
+
and stripped_content.startswith("{%")
|
| 96 |
+
and not stripped_content.startswith("{%-")
|
| 97 |
+
):
|
| 98 |
+
# Add '-' at the beginning
|
| 99 |
+
result = (
|
| 100 |
+
result[: result.rfind("{%")]
|
| 101 |
+
+ "{%-"
|
| 102 |
+
+ result[result.rfind("{%") + 2 :]
|
| 103 |
+
)
|
| 104 |
+
if stripped_content.endswith("%}") and not stripped_content.endswith(
|
| 105 |
+
"-%}"
|
| 106 |
+
):
|
| 107 |
+
# Only add '-' if this is not the last token or if there's content after
|
| 108 |
+
if i + 1 < len(tokens) and tokens[i + 1][1] != "eof":
|
| 109 |
+
result = result[:-2] + "-%}"
|
| 110 |
+
|
| 111 |
+
# For control start blocks, increase indent AFTER adding the content
|
| 112 |
+
if is_control_start:
|
| 113 |
+
indent_level += 1
|
| 114 |
+
else:
|
| 115 |
+
# Malformed template, just add the token
|
| 116 |
+
result += token_value
|
| 117 |
+
elif token_type == "variable_begin":
|
| 118 |
+
# Collect all tokens for this variable construct
|
| 119 |
+
construct_content = token_value
|
| 120 |
+
end_token_type = token_type.replace("_begin", "_end")
|
| 121 |
+
j = i + 1
|
| 122 |
+
while j < len(tokens) and tokens[j][1] != end_token_type:
|
| 123 |
+
construct_content += tokens[j][2]
|
| 124 |
+
j += 1
|
| 125 |
+
|
| 126 |
+
if j < len(tokens): # Found the end token
|
| 127 |
+
construct_content += tokens[j][2]
|
| 128 |
+
i = j # Skip to the end token
|
| 129 |
+
|
| 130 |
+
# For variable constructs, leave them alone
|
| 131 |
+
# Do not add indent or whitespace before or after them
|
| 132 |
+
result += construct_content
|
| 133 |
+
else:
|
| 134 |
+
# Malformed template, just add the token
|
| 135 |
+
result += token_value
|
| 136 |
+
elif token_type == "data":
|
| 137 |
+
# Handle data (text between Jinja constructs)
|
| 138 |
+
# For data content, preserve it as is
|
| 139 |
+
result += token_value
|
| 140 |
+
else:
|
| 141 |
+
# Handle any other tokens
|
| 142 |
+
result += token_value
|
| 143 |
+
|
| 144 |
+
i += 1
|
| 145 |
+
|
| 146 |
+
# Clean up trailing newlines and spaces
|
| 147 |
+
result = result.rstrip()
|
| 148 |
+
|
| 149 |
+
# Copy the newline / space count from the original
|
| 150 |
+
if (trailing_length := len(template_content) - len(tc_rstrip)):
|
| 151 |
+
result += template_content[-trailing_length:]
|
| 152 |
+
|
| 153 |
+
return result
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
# ------------------------
|
| 157 |
+
# Line Number Widget
|
| 158 |
+
# ------------------------
|
| 159 |
+
class LineNumberArea(QWidget):
|
| 160 |
+
def __init__(self, editor):
|
| 161 |
+
super().__init__(editor)
|
| 162 |
+
self.code_editor = editor
|
| 163 |
+
|
| 164 |
+
def sizeHint(self):
|
| 165 |
+
return QSize(self.code_editor.line_number_area_width(), 0)
|
| 166 |
+
|
| 167 |
+
def paintEvent(self, event):
|
| 168 |
+
self.code_editor.line_number_area_paint_event(event)
|
| 169 |
+
|
| 170 |
+
|
| 171 |
+
class CodeEditor(QPlainTextEdit):
|
| 172 |
+
def __init__(self):
|
| 173 |
+
super().__init__()
|
| 174 |
+
self.line_number_area = LineNumberArea(self)
|
| 175 |
+
|
| 176 |
+
self.blockCountChanged.connect(self.update_line_number_area_width)
|
| 177 |
+
self.updateRequest.connect(self.update_line_number_area)
|
| 178 |
+
self.cursorPositionChanged.connect(self.highlight_current_line)
|
| 179 |
+
|
| 180 |
+
self.update_line_number_area_width(0)
|
| 181 |
+
self.highlight_current_line()
|
| 182 |
+
|
| 183 |
+
def line_number_area_width(self):
|
| 184 |
+
digits = len(str(self.blockCount()))
|
| 185 |
+
space = 3 + self.fontMetrics().horizontalAdvance("9") * digits
|
| 186 |
+
return space
|
| 187 |
+
|
| 188 |
+
def update_line_number_area_width(self, _):
|
| 189 |
+
self.setViewportMargins(self.line_number_area_width(), 0, 0, 0)
|
| 190 |
+
|
| 191 |
+
def update_line_number_area(self, rect, dy):
|
| 192 |
+
if dy:
|
| 193 |
+
self.line_number_area.scroll(0, dy)
|
| 194 |
+
else:
|
| 195 |
+
self.line_number_area.update(
|
| 196 |
+
0, rect.y(), self.line_number_area.width(), rect.height()
|
| 197 |
+
)
|
| 198 |
+
|
| 199 |
+
if rect.contains(self.viewport().rect()):
|
| 200 |
+
self.update_line_number_area_width(0)
|
| 201 |
+
|
| 202 |
+
def resizeEvent(self, event):
|
| 203 |
+
super().resizeEvent(event)
|
| 204 |
+
cr = self.contentsRect()
|
| 205 |
+
self.line_number_area.setGeometry(
|
| 206 |
+
QRect(cr.left(), cr.top(), self.line_number_area_width(), cr.height())
|
| 207 |
+
)
|
| 208 |
+
|
| 209 |
+
def line_number_area_paint_event(self, event):
|
| 210 |
+
from PySide6.QtGui import QPainter
|
| 211 |
+
|
| 212 |
+
painter = QPainter(self.line_number_area)
|
| 213 |
+
painter.fillRect(event.rect(), QColorConstants.LightGray)
|
| 214 |
+
|
| 215 |
+
block = self.firstVisibleBlock()
|
| 216 |
+
block_number = block.blockNumber()
|
| 217 |
+
top = int(
|
| 218 |
+
self.blockBoundingGeometry(block).translated(self.contentOffset()).top()
|
| 219 |
+
)
|
| 220 |
+
bottom = top + int(self.blockBoundingRect(block).height())
|
| 221 |
+
|
| 222 |
+
while block.isValid() and top <= event.rect().bottom():
|
| 223 |
+
if block.isVisible() and bottom >= event.rect().top():
|
| 224 |
+
number = str(block_number + 1)
|
| 225 |
+
painter.setPen(QColorConstants.Black)
|
| 226 |
+
painter.drawText(
|
| 227 |
+
0,
|
| 228 |
+
top,
|
| 229 |
+
self.line_number_area.width() - 2,
|
| 230 |
+
self.fontMetrics().height(),
|
| 231 |
+
Qt.AlignmentFlag.AlignRight,
|
| 232 |
+
number,
|
| 233 |
+
)
|
| 234 |
+
block = block.next()
|
| 235 |
+
top = bottom
|
| 236 |
+
bottom = top + int(self.blockBoundingRect(block).height())
|
| 237 |
+
block_number += 1
|
| 238 |
+
|
| 239 |
+
def highlight_current_line(self):
|
| 240 |
+
extra_selections = []
|
| 241 |
+
if not self.isReadOnly():
|
| 242 |
+
selection = QTextEdit.ExtraSelection()
|
| 243 |
+
line_color = QColorConstants.Yellow.lighter(160)
|
| 244 |
+
selection.format.setBackground(line_color) # pyright: ignore[reportAttributeAccessIssue]
|
| 245 |
+
selection.format.setProperty(QTextFormat.Property.FullWidthSelection, True) # pyright: ignore[reportAttributeAccessIssue]
|
| 246 |
+
selection.cursor = self.textCursor() # pyright: ignore[reportAttributeAccessIssue]
|
| 247 |
+
selection.cursor.clearSelection() # pyright: ignore[reportAttributeAccessIssue]
|
| 248 |
+
extra_selections.append(selection)
|
| 249 |
+
self.setExtraSelections(extra_selections)
|
| 250 |
+
|
| 251 |
+
def highlight_position(self, lineno: int, col: int, color: QColor):
|
| 252 |
+
block = self.document().findBlockByLineNumber(lineno - 1)
|
| 253 |
+
if block.isValid():
|
| 254 |
+
cursor = QTextCursor(block)
|
| 255 |
+
text = block.text()
|
| 256 |
+
start = block.position() + max(0, col - 1)
|
| 257 |
+
cursor.setPosition(start)
|
| 258 |
+
if col <= len(text):
|
| 259 |
+
cursor.movePosition(
|
| 260 |
+
QTextCursor.MoveOperation.NextCharacter,
|
| 261 |
+
QTextCursor.MoveMode.KeepAnchor,
|
| 262 |
+
)
|
| 263 |
+
|
| 264 |
+
extra = QTextEdit.ExtraSelection()
|
| 265 |
+
extra.format.setBackground(color.lighter(160)) # pyright: ignore[reportAttributeAccessIssue]
|
| 266 |
+
extra.cursor = cursor # pyright: ignore[reportAttributeAccessIssue]
|
| 267 |
+
|
| 268 |
+
self.setExtraSelections(self.extraSelections() + [extra])
|
| 269 |
+
|
| 270 |
+
def highlight_line(self, lineno: int, color: QColor):
|
| 271 |
+
block = self.document().findBlockByLineNumber(lineno - 1)
|
| 272 |
+
if block.isValid():
|
| 273 |
+
cursor = QTextCursor(block)
|
| 274 |
+
cursor.select(QTextCursor.SelectionType.LineUnderCursor)
|
| 275 |
+
|
| 276 |
+
extra = QTextEdit.ExtraSelection()
|
| 277 |
+
extra.format.setBackground(color.lighter(160)) # pyright: ignore[reportAttributeAccessIssue]
|
| 278 |
+
extra.cursor = cursor # pyright: ignore[reportAttributeAccessIssue]
|
| 279 |
+
|
| 280 |
+
self.setExtraSelections(self.extraSelections() + [extra])
|
| 281 |
+
|
| 282 |
+
def clear_highlighting(self):
|
| 283 |
+
self.highlight_current_line()
|
| 284 |
+
|
| 285 |
+
|
| 286 |
+
# ------------------------
|
| 287 |
+
# Main App
|
| 288 |
+
# ------------------------
|
| 289 |
+
class JinjaTester(QMainWindow):
|
| 290 |
+
def __init__(self):
|
| 291 |
+
super().__init__()
|
| 292 |
+
self.setWindowTitle("Jinja Template Tester")
|
| 293 |
+
self.resize(1200, 800)
|
| 294 |
+
|
| 295 |
+
central = QWidget()
|
| 296 |
+
main_layout = QVBoxLayout(central)
|
| 297 |
+
|
| 298 |
+
# -------- Top input area --------
|
| 299 |
+
input_layout = QHBoxLayout()
|
| 300 |
+
|
| 301 |
+
# Template editor with label
|
| 302 |
+
template_layout = QVBoxLayout()
|
| 303 |
+
template_label = QLabel("Jinja2 Template")
|
| 304 |
+
template_layout.addWidget(template_label)
|
| 305 |
+
self.template_edit = CodeEditor()
|
| 306 |
+
template_layout.addWidget(self.template_edit)
|
| 307 |
+
input_layout.addLayout(template_layout)
|
| 308 |
+
|
| 309 |
+
# JSON editor with label
|
| 310 |
+
json_layout = QVBoxLayout()
|
| 311 |
+
json_label = QLabel("Context (JSON)")
|
| 312 |
+
json_layout.addWidget(json_label)
|
| 313 |
+
self.json_edit = CodeEditor()
|
| 314 |
+
self.json_edit.setPlainText("""
|
| 315 |
+
{
|
| 316 |
+
"add_generation_prompt": true,
|
| 317 |
+
"bos_token": "",
|
| 318 |
+
"eos_token": "",
|
| 319 |
+
"messages": [
|
| 320 |
+
{
|
| 321 |
+
"role": "user",
|
| 322 |
+
"content": "What is the capital of Poland?"
|
| 323 |
+
}
|
| 324 |
+
]
|
| 325 |
+
}
|
| 326 |
+
""".strip())
|
| 327 |
+
json_layout.addWidget(self.json_edit)
|
| 328 |
+
input_layout.addLayout(json_layout)
|
| 329 |
+
|
| 330 |
+
main_layout.addLayout(input_layout)
|
| 331 |
+
|
| 332 |
+
# -------- Rendered output area --------
|
| 333 |
+
output_label = QLabel("Rendered Output")
|
| 334 |
+
main_layout.addWidget(output_label)
|
| 335 |
+
self.output_edit = QPlainTextEdit()
|
| 336 |
+
self.output_edit.setReadOnly(True)
|
| 337 |
+
main_layout.addWidget(self.output_edit)
|
| 338 |
+
|
| 339 |
+
# -------- Render button and status --------
|
| 340 |
+
btn_layout = QHBoxLayout()
|
| 341 |
+
|
| 342 |
+
# Load template button
|
| 343 |
+
self.load_btn = QPushButton("Load Template")
|
| 344 |
+
self.load_btn.clicked.connect(self.load_template)
|
| 345 |
+
btn_layout.addWidget(self.load_btn)
|
| 346 |
+
|
| 347 |
+
# Format template button
|
| 348 |
+
self.format_btn = QPushButton("Format")
|
| 349 |
+
self.format_btn.clicked.connect(self.format_template)
|
| 350 |
+
btn_layout.addWidget(self.format_btn)
|
| 351 |
+
|
| 352 |
+
self.render_btn = QPushButton("Render")
|
| 353 |
+
self.render_btn.clicked.connect(self.render_template)
|
| 354 |
+
btn_layout.addWidget(self.render_btn)
|
| 355 |
+
main_layout.addLayout(btn_layout)
|
| 356 |
+
|
| 357 |
+
# Status label below buttons
|
| 358 |
+
self.status_label = QLabel("Ready")
|
| 359 |
+
main_layout.addWidget(self.status_label)
|
| 360 |
+
|
| 361 |
+
self.setCentralWidget(central)
|
| 362 |
+
|
| 363 |
+
def render_template(self):
|
| 364 |
+
self.template_edit.clear_highlighting()
|
| 365 |
+
self.output_edit.clear()
|
| 366 |
+
|
| 367 |
+
template_str = self.template_edit.toPlainText()
|
| 368 |
+
json_str = self.json_edit.toPlainText()
|
| 369 |
+
|
| 370 |
+
# Parse JSON context
|
| 371 |
+
try:
|
| 372 |
+
context = json.loads(json_str) if json_str.strip() else {}
|
| 373 |
+
except Exception as e:
|
| 374 |
+
self.status_label.setText(f"❌ JSON Error: {e}")
|
| 375 |
+
return
|
| 376 |
+
|
| 377 |
+
def raise_exception(text: str) -> str:
|
| 378 |
+
raise RuntimeError(text)
|
| 379 |
+
|
| 380 |
+
env = ImmutableSandboxedEnvironment(
|
| 381 |
+
trim_blocks=True,
|
| 382 |
+
lstrip_blocks=True,
|
| 383 |
+
extensions=[jinja2_ext.loopcontrols],
|
| 384 |
+
)
|
| 385 |
+
env.filters["tojson"] = (
|
| 386 |
+
lambda x,
|
| 387 |
+
indent=None,
|
| 388 |
+
separators=None,
|
| 389 |
+
sort_keys=False,
|
| 390 |
+
ensure_ascii=False: json.dumps(
|
| 391 |
+
x,
|
| 392 |
+
indent=indent,
|
| 393 |
+
separators=separators,
|
| 394 |
+
sort_keys=sort_keys,
|
| 395 |
+
ensure_ascii=ensure_ascii,
|
| 396 |
+
)
|
| 397 |
+
)
|
| 398 |
+
env.globals["strftime_now"] = lambda format: datetime.now().strftime(format)
|
| 399 |
+
env.globals["raise_exception"] = raise_exception
|
| 400 |
+
try:
|
| 401 |
+
template = env.from_string(template_str)
|
| 402 |
+
output = template.render(context)
|
| 403 |
+
self.output_edit.setPlainText(output)
|
| 404 |
+
self.status_label.setText("✅ Render successful")
|
| 405 |
+
except TemplateSyntaxError as e:
|
| 406 |
+
self.status_label.setText(f"❌ Syntax Error (line {e.lineno}): {e.message}")
|
| 407 |
+
if e.lineno:
|
| 408 |
+
self.template_edit.highlight_line(e.lineno, QColor("red"))
|
| 409 |
+
except Exception as e:
|
| 410 |
+
# Catch all runtime errors
|
| 411 |
+
# Try to extract template line number
|
| 412 |
+
lineno = None
|
| 413 |
+
tb = e.__traceback__
|
| 414 |
+
while tb:
|
| 415 |
+
frame = tb.tb_frame
|
| 416 |
+
if frame.f_code.co_filename == "<template>":
|
| 417 |
+
lineno = tb.tb_lineno
|
| 418 |
+
break
|
| 419 |
+
tb = tb.tb_next
|
| 420 |
+
|
| 421 |
+
error_msg = f"Runtime Error: {type(e).__name__}: {e}"
|
| 422 |
+
if lineno:
|
| 423 |
+
error_msg = f"Runtime Error at line {lineno} in template: {type(e).__name__}: {e}"
|
| 424 |
+
self.template_edit.highlight_line(lineno, QColor("orange"))
|
| 425 |
+
|
| 426 |
+
self.output_edit.setPlainText(error_msg)
|
| 427 |
+
self.status_label.setText(f"❌ {error_msg}")
|
| 428 |
+
|
| 429 |
+
def load_template(self):
|
| 430 |
+
"""Load a Jinja template from a file using a file dialog."""
|
| 431 |
+
file_path, _ = QFileDialog.getOpenFileName(
|
| 432 |
+
self,
|
| 433 |
+
"Load Jinja Template",
|
| 434 |
+
"",
|
| 435 |
+
"Template Files (*.jinja *.j2 *.html *.txt);;All Files (*)",
|
| 436 |
+
)
|
| 437 |
+
|
| 438 |
+
if file_path:
|
| 439 |
+
try:
|
| 440 |
+
with open(file_path, "r", encoding="utf-8") as file:
|
| 441 |
+
content = file.read()
|
| 442 |
+
self.template_edit.setPlainText(content)
|
| 443 |
+
self.status_label.setText(f"✅ Loaded template from {file_path}")
|
| 444 |
+
except Exception as e:
|
| 445 |
+
self.status_label.setText(f"❌ Error loading file: {str(e)}")
|
| 446 |
+
|
| 447 |
+
def format_template(self):
|
| 448 |
+
"""Format the Jinja template using Jinja2's lexer for proper parsing."""
|
| 449 |
+
try:
|
| 450 |
+
template_content = self.template_edit.toPlainText()
|
| 451 |
+
if not template_content.strip():
|
| 452 |
+
self.status_label.setText("⚠️ Template is empty")
|
| 453 |
+
return
|
| 454 |
+
|
| 455 |
+
formatted_content = format_template_content(template_content)
|
| 456 |
+
self.template_edit.setPlainText(formatted_content)
|
| 457 |
+
self.status_label.setText("✅ Template formatted")
|
| 458 |
+
except Exception as e:
|
| 459 |
+
self.status_label.setText(f"❌ Error formatting template: {str(e)}")
|
| 460 |
+
|
| 461 |
+
|
| 462 |
+
if __name__ == "__main__":
|
| 463 |
+
if len(sys.argv) > 1:
|
| 464 |
+
# CLI mode
|
| 465 |
+
parser = argparse.ArgumentParser(description="Jinja Template Tester")
|
| 466 |
+
parser.add_argument(
|
| 467 |
+
"--template", required=True, help="Path to Jinja template file"
|
| 468 |
+
)
|
| 469 |
+
parser.add_argument("--context", required=True, help="JSON string for context")
|
| 470 |
+
parser.add_argument(
|
| 471 |
+
"--action",
|
| 472 |
+
choices=["format", "render"],
|
| 473 |
+
default="render",
|
| 474 |
+
help="Action to perform",
|
| 475 |
+
)
|
| 476 |
+
args = parser.parse_args()
|
| 477 |
+
|
| 478 |
+
# Load template
|
| 479 |
+
with open(args.template, "r", encoding="utf-8") as f:
|
| 480 |
+
template_content = f.read()
|
| 481 |
+
|
| 482 |
+
# Load JSON
|
| 483 |
+
context = json.loads(args.context)
|
| 484 |
+
# Add missing variables
|
| 485 |
+
context.setdefault("bos_token", "")
|
| 486 |
+
context.setdefault("eos_token", "")
|
| 487 |
+
context.setdefault("add_generation_prompt", False)
|
| 488 |
+
|
| 489 |
+
env = ImmutableSandboxedEnvironment()
|
| 490 |
+
|
| 491 |
+
if args.action == "format":
|
| 492 |
+
formatted = format_template_content(template_content)
|
| 493 |
+
print(formatted) # noqa: NP100
|
| 494 |
+
elif args.action == "render":
|
| 495 |
+
template = env.from_string(template_content)
|
| 496 |
+
output = template.render(context)
|
| 497 |
+
print(output) # noqa: NP100
|
| 498 |
+
|
| 499 |
+
else:
|
| 500 |
+
# GUI mode
|
| 501 |
+
app = QApplication(sys.argv)
|
| 502 |
+
window = JinjaTester()
|
| 503 |
+
window.show()
|
| 504 |
+
sys.exit(app.exec())
|
llama.cpp/scripts/jinja/requirements.txt
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
PySide6
|
| 2 |
+
jinja2
|
llama.cpp/scripts/snapdragon/adb/llama-cli.farf
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
0xffff
|
llama.cpp/scripts/snapdragon/adb/run-bench.sh
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
#
|
| 3 |
+
|
| 4 |
+
# Basedir on device
|
| 5 |
+
basedir=/data/local/tmp/llama.cpp
|
| 6 |
+
|
| 7 |
+
branch=.
|
| 8 |
+
[ "$B" != "" ] && branch=$B
|
| 9 |
+
|
| 10 |
+
adbserial=
|
| 11 |
+
[ "$S" != "" ] && adbserial="-s $S"
|
| 12 |
+
|
| 13 |
+
adbhost=
|
| 14 |
+
[ "$H" != "" ] && adbhost="-H $H"
|
| 15 |
+
|
| 16 |
+
model="Llama-3.2-3B-Instruct-Q4_0.gguf"
|
| 17 |
+
[ "$M" != "" ] && model="$M"
|
| 18 |
+
|
| 19 |
+
device="HTP0"
|
| 20 |
+
[ "$D" != "" ] && device="$D"
|
| 21 |
+
|
| 22 |
+
verbose=
|
| 23 |
+
[ "$V" != "" ] && verbose="GGML_HEXAGON_VERBOSE=$V" cli_opts="$cli_opts -v"
|
| 24 |
+
|
| 25 |
+
experimental=
|
| 26 |
+
[ "$E" != "" ] && experimental="GGML_HEXAGON_EXPERIMENTAL=$E"
|
| 27 |
+
|
| 28 |
+
profile=
|
| 29 |
+
[ "$PROF" != "" ] && profile="GGML_HEXAGON_PROFILE=$PROF GGML_HEXAGON_OPSYNC=1" cli_opts="$cli_opts -v"
|
| 30 |
+
|
| 31 |
+
opmask=
|
| 32 |
+
[ "$OPMASK" != "" ] && opmask="GGML_HEXAGON_OPMASK=$OPMASK"
|
| 33 |
+
|
| 34 |
+
nhvx=
|
| 35 |
+
[ "$NHVX" != "" ] && nhvx="GGML_HEXAGON_NHVX=$NHVX"
|
| 36 |
+
|
| 37 |
+
ndev=
|
| 38 |
+
[ "$NDEV" != "" ] && ndev="GGML_HEXAGON_NDEV=$NDEV"
|
| 39 |
+
|
| 40 |
+
hb=
|
| 41 |
+
[ "$HB" != "" ] && hb="GGML_HEXAGON_HOSTBUF=$HB"
|
| 42 |
+
|
| 43 |
+
set -x
|
| 44 |
+
|
| 45 |
+
adb $adbserial $adbhost shell " \
|
| 46 |
+
cd $basedir; \
|
| 47 |
+
LD_LIBRARY_PATH=$basedir/$branch/lib \
|
| 48 |
+
ADSP_LIBRARY_PATH=$basedir/$branch/lib \
|
| 49 |
+
$ndev $nhvx $opmask $verbose $experimental $profile $hb ./$branch/bin/llama-bench --device $device --mmap 0 -m $basedir/../gguf/$model \
|
| 50 |
+
--poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 \
|
| 51 |
+
--batch-size 128 -ngl 99 $cli_opts $@ \
|
| 52 |
+
"
|
llama.cpp/scripts/snapdragon/adb/run-cli.sh
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
#
|
| 3 |
+
|
| 4 |
+
# Basedir on device
|
| 5 |
+
basedir=/data/local/tmp/llama.cpp
|
| 6 |
+
|
| 7 |
+
cli_opts=
|
| 8 |
+
|
| 9 |
+
branch=.
|
| 10 |
+
[ "$B" != "" ] && branch=$B
|
| 11 |
+
|
| 12 |
+
adbserial=
|
| 13 |
+
[ "$S" != "" ] && adbserial="-s $S"
|
| 14 |
+
|
| 15 |
+
adbhost=
|
| 16 |
+
[ "$H" != "" ] && adbhost="-H $H"
|
| 17 |
+
|
| 18 |
+
model="Llama-3.2-3B-Instruct-Q4_0.gguf"
|
| 19 |
+
[ "$M" != "" ] && model="$M"
|
| 20 |
+
|
| 21 |
+
device="HTP0"
|
| 22 |
+
[ "$D" != "" ] && device="$D"
|
| 23 |
+
|
| 24 |
+
experimental=
|
| 25 |
+
[ "$E" != "" ] && experimental="GGML_HEXAGON_EXPERIMENTAL=$E"
|
| 26 |
+
|
| 27 |
+
verbose=
|
| 28 |
+
[ "$V" != "" ] && verbose="GGML_HEXAGON_VERBOSE=$V" cli_opts="$cli_opts -v"
|
| 29 |
+
|
| 30 |
+
sched=
|
| 31 |
+
[ "$SCHED" != "" ] && sched="GGML_SCHED_DEBUG=2" cli_opts="$cli_opts -v"
|
| 32 |
+
|
| 33 |
+
profile=
|
| 34 |
+
[ "$PROF" != "" ] && profile="GGML_HEXAGON_PROFILE=$PROF GGML_HEXAGON_OPSYNC=1" cli_opts="$cli_opts -v"
|
| 35 |
+
|
| 36 |
+
opmask=
|
| 37 |
+
[ "$OPMASK" != "" ] && opmask="GGML_HEXAGON_OPMASK=$OPMASK"
|
| 38 |
+
|
| 39 |
+
nhvx=
|
| 40 |
+
[ "$NHVX" != "" ] && nhvx="GGML_HEXAGON_NHVX=$NHVX"
|
| 41 |
+
|
| 42 |
+
ndev=
|
| 43 |
+
[ "$NDEV" != "" ] && ndev="GGML_HEXAGON_NDEV=$NDEV"
|
| 44 |
+
|
| 45 |
+
hb=
|
| 46 |
+
[ "$HB" != "" ] && hb="GGML_HEXAGON_HOSTBUF=$HB"
|
| 47 |
+
|
| 48 |
+
set -x
|
| 49 |
+
|
| 50 |
+
adb $adbserial $adbhost shell " \
|
| 51 |
+
cd $basedir; ulimit -c unlimited; \
|
| 52 |
+
LD_LIBRARY_PATH=$basedir/$branch/lib \
|
| 53 |
+
ADSP_LIBRARY_PATH=$basedir/$branch/lib \
|
| 54 |
+
$verbose $experimental $sched $opmask $profile $nhvx $ndev $hb \
|
| 55 |
+
./$branch/bin/llama-cli --no-mmap -m $basedir/../gguf/$model \
|
| 56 |
+
--poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 \
|
| 57 |
+
--ctx-size 8192 --ubatch-size 256 -fa on \
|
| 58 |
+
-ngl 99 --device $device $cli_opts $@ \
|
| 59 |
+
"
|
llama.cpp/scripts/snapdragon/adb/run-completion.sh
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
#
|
| 3 |
+
|
| 4 |
+
# Basedir on device
|
| 5 |
+
basedir=/data/local/tmp/llama.cpp
|
| 6 |
+
|
| 7 |
+
cli_opts=
|
| 8 |
+
|
| 9 |
+
branch=.
|
| 10 |
+
[ "$B" != "" ] && branch=$B
|
| 11 |
+
|
| 12 |
+
adbserial=
|
| 13 |
+
[ "$S" != "" ] && adbserial="-s $S"
|
| 14 |
+
|
| 15 |
+
adbhost=
|
| 16 |
+
[ "$H" != "" ] && adbhost="-H $H"
|
| 17 |
+
|
| 18 |
+
model="Llama-3.2-3B-Instruct-Q4_0.gguf"
|
| 19 |
+
[ "$M" != "" ] && model="$M"
|
| 20 |
+
|
| 21 |
+
device="HTP0"
|
| 22 |
+
[ "$D" != "" ] && device="$D"
|
| 23 |
+
|
| 24 |
+
experimental=
|
| 25 |
+
[ "$E" != "" ] && experimental="GGML_HEXAGON_EXPERIMENTAL=$E"
|
| 26 |
+
|
| 27 |
+
verbose=
|
| 28 |
+
[ "$V" != "" ] && verbose="GGML_HEXAGON_VERBOSE=$V" cli_opts="$cli_opts -v"
|
| 29 |
+
|
| 30 |
+
sched=
|
| 31 |
+
[ "$SCHED" != "" ] && sched="GGML_SCHED_DEBUG=2" cli_opts="$cli_opts -v"
|
| 32 |
+
|
| 33 |
+
profile=
|
| 34 |
+
[ "$PROF" != "" ] && profile="GGML_HEXAGON_PROFILE=$PROF GGML_HEXAGON_OPSYNC=1" cli_opts="$cli_opts -v"
|
| 35 |
+
|
| 36 |
+
opmask=
|
| 37 |
+
[ "$OPMASK" != "" ] && opmask="GGML_HEXAGON_OPMASK=$OPMASK"
|
| 38 |
+
|
| 39 |
+
nhvx=
|
| 40 |
+
[ "$NHVX" != "" ] && nhvx="GGML_HEXAGON_NHVX=$NHVX"
|
| 41 |
+
|
| 42 |
+
ndev=
|
| 43 |
+
[ "$NDEV" != "" ] && ndev="GGML_HEXAGON_NDEV=$NDEV"
|
| 44 |
+
|
| 45 |
+
hb=
|
| 46 |
+
[ "$HB" != "" ] && hb="GGML_HEXAGON_HOSTBUF=$HB"
|
| 47 |
+
|
| 48 |
+
set -x
|
| 49 |
+
|
| 50 |
+
adb $adbserial $adbhost shell " \
|
| 51 |
+
cd $basedir; ulimit -c unlimited; \
|
| 52 |
+
LD_LIBRARY_PATH=$basedir/$branch/lib \
|
| 53 |
+
ADSP_LIBRARY_PATH=$basedir/$branch/lib \
|
| 54 |
+
$verbose $experimental $sched $opmask $profile $nhvx $ndev $hb \
|
| 55 |
+
./$branch/bin/llama-completion --no-mmap -m $basedir/../gguf/$model \
|
| 56 |
+
--poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 \
|
| 57 |
+
--ctx-size 8192 --ubatch-size 256 -fa on \
|
| 58 |
+
-ngl 99 -no-cnv --device $device $cli_opts $@ \
|
| 59 |
+
"
|
llama.cpp/scripts/snapdragon/adb/run-mtmd.sh
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
#
|
| 3 |
+
|
| 4 |
+
# Basedir on device
|
| 5 |
+
basedir=/data/local/tmp/llama.cpp
|
| 6 |
+
|
| 7 |
+
cli_opts=
|
| 8 |
+
|
| 9 |
+
branch=.
|
| 10 |
+
[ "$B" != "" ] && branch=$B
|
| 11 |
+
|
| 12 |
+
adbserial=
|
| 13 |
+
[ "$S" != "" ] && adbserial="-s $S"
|
| 14 |
+
|
| 15 |
+
adbhost=
|
| 16 |
+
[ "$H" != "" ] && adbhost="-H $H"
|
| 17 |
+
|
| 18 |
+
model="gemma-3-4b-it-Q4_0.gguf"
|
| 19 |
+
[ "$M" != "" ] && model="$M"
|
| 20 |
+
|
| 21 |
+
mmproj="mmproj-F16.gguf"
|
| 22 |
+
[ "$MMPROJ" != "" ] && mmproj="$MMPROJ"
|
| 23 |
+
|
| 24 |
+
image=
|
| 25 |
+
[ "$IMG" != "" ] && image="$IMG"
|
| 26 |
+
|
| 27 |
+
device="HTP0"
|
| 28 |
+
[ "$D" != "" ] && device="$D"
|
| 29 |
+
|
| 30 |
+
verbose=
|
| 31 |
+
[ "$V" != "" ] && verbose="GGML_HEXAGON_VERBOSE=$V"
|
| 32 |
+
|
| 33 |
+
experimental="GGML_HEXAGON_EXPERIMENTAL=1"
|
| 34 |
+
[ "$E" != "" ] && experimental="GGML_HEXAGON_EXPERIMENTAL=$E"
|
| 35 |
+
|
| 36 |
+
sched=
|
| 37 |
+
[ "$SCHED" != "" ] && sched="GGML_SCHED_DEBUG=2" cli_opts="$cli_opts -v"
|
| 38 |
+
|
| 39 |
+
profile=
|
| 40 |
+
[ "$PROF" != "" ] && profile="GGML_HEXAGON_PROFILE=$PROF GGML_HEXAGON_OPSYNC=1"
|
| 41 |
+
|
| 42 |
+
opmask=
|
| 43 |
+
[ "$OPMASK" != "" ] && opmask="GGML_HEXAGON_OPMASK=$OPMASK"
|
| 44 |
+
|
| 45 |
+
nhvx=
|
| 46 |
+
[ "$NHVX" != "" ] && nhvx="GGML_HEXAGON_NHVX=$NHVX"
|
| 47 |
+
|
| 48 |
+
ndev=
|
| 49 |
+
[ "$NDEV" != "" ] && ndev="GGML_HEXAGON_NDEV=$NDEV"
|
| 50 |
+
|
| 51 |
+
# MTMD backend device for vision model (defaults to CPU if not set)
|
| 52 |
+
mtmd_backend=
|
| 53 |
+
[ "$MTMD_DEVICE" != "" ] && mtmd_backend="MTMD_BACKEND_DEVICE=$MTMD_DEVICE"
|
| 54 |
+
|
| 55 |
+
set -x
|
| 56 |
+
|
| 57 |
+
adb $adbserial $adbhost shell " \
|
| 58 |
+
cd $basedir; ulimit -c unlimited; \
|
| 59 |
+
LD_LIBRARY_PATH=$basedir/$branch/lib \
|
| 60 |
+
ADSP_LIBRARY_PATH=$basedir/$branch/lib \
|
| 61 |
+
$verbose $experimental $sched $opmask $profile $nhvx $ndev $mtmd_backend \
|
| 62 |
+
./$branch/bin/llama-mtmd-cli --no-mmap -m $basedir/../gguf/$model \
|
| 63 |
+
--mmproj $basedir/../gguf/$mmproj \
|
| 64 |
+
--image $basedir/../gguf/$image \
|
| 65 |
+
--poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 \
|
| 66 |
+
--ctx-size 8192 --ubatch-size 256 -fa on \
|
| 67 |
+
-ngl 99 --device $device -v $cli_opts $@ \
|
| 68 |
+
"
|
llama.cpp/scripts/snapdragon/adb/run-tool.sh
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
#
|
| 3 |
+
|
| 4 |
+
# Basedir on device
|
| 5 |
+
basedir=/data/local/tmp/llama.cpp
|
| 6 |
+
|
| 7 |
+
cli_opts=
|
| 8 |
+
|
| 9 |
+
branch=.
|
| 10 |
+
[ "$B" != "" ] && branch=$B
|
| 11 |
+
|
| 12 |
+
adbserial=
|
| 13 |
+
[ "$S" != "" ] && adbserial="-s $S"
|
| 14 |
+
|
| 15 |
+
adbhost=
|
| 16 |
+
[ "$H" != "" ] && adbhost="-H $H"
|
| 17 |
+
|
| 18 |
+
device="HTP0"
|
| 19 |
+
[ "$D" != "" ] && device="$D"
|
| 20 |
+
|
| 21 |
+
verbose=
|
| 22 |
+
[ "$V" != "" ] && verbose="GGML_HEXAGON_VERBOSE=$V"
|
| 23 |
+
|
| 24 |
+
experimental=
|
| 25 |
+
[ "$E" != "" ] && experimental="GGML_HEXAGON_EXPERIMENTAL=$E"
|
| 26 |
+
|
| 27 |
+
sched=
|
| 28 |
+
[ "$SCHED" != "" ] && sched="GGML_SCHED_DEBUG=2" cli_opts="$cli_opts -v"
|
| 29 |
+
|
| 30 |
+
profile=
|
| 31 |
+
[ "$PROF" != "" ] && profile="GGML_HEXAGON_PROFILE=$PROF GGML_HEXAGON_OPSYNC=1"
|
| 32 |
+
|
| 33 |
+
opmask=
|
| 34 |
+
[ "$OPMASK" != "" ] && opmask="GGML_HEXAGON_OPMASK=$OPMASK"
|
| 35 |
+
|
| 36 |
+
nhvx=
|
| 37 |
+
[ "$NHVX" != "" ] && nhvx="GGML_HEXAGON_NHVX=$NHVX"
|
| 38 |
+
|
| 39 |
+
ndev=
|
| 40 |
+
[ "$NDEV" != "" ] && ndev="GGML_HEXAGON_NDEV=$NDEV"
|
| 41 |
+
|
| 42 |
+
hb=
|
| 43 |
+
[ "$HB" != "" ] && hb="GGML_HEXAGON_HOSTBUF=$HB"
|
| 44 |
+
|
| 45 |
+
set -x
|
| 46 |
+
|
| 47 |
+
tool=$1; shift
|
| 48 |
+
|
| 49 |
+
adb $adbserial $adbhost shell " \
|
| 50 |
+
cd $basedir; ulimit -c unlimited; \
|
| 51 |
+
LD_LIBRARY_PATH=$basedir/$branch/lib \
|
| 52 |
+
ADSP_LIBRARY_PATH=$basedir/$branch/lib \
|
| 53 |
+
$verbose $experimental $sched $opmask $profile $nhvx $ndev $hb ./$branch/bin/$tool $@ \
|
| 54 |
+
"
|
llama.cpp/scripts/snapdragon/qdc/readme.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
This directory includes pytest based scripts for running CI jobs on Qualcomm Device Cloud (QDC).
|
llama.cpp/scripts/snapdragon/qdc/requirements.txt
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Appium-Python-Client==5.2.4
|
| 2 |
+
attrs==25.4.0
|
| 3 |
+
certifi==2025.10.5
|
| 4 |
+
exceptiongroup==1.3.0
|
| 5 |
+
h11==0.16.0
|
| 6 |
+
idna==3.11
|
| 7 |
+
iniconfig==2.1.0
|
| 8 |
+
outcome==1.3.0.post0
|
| 9 |
+
packaging==25.0
|
| 10 |
+
pluggy==1.6.0
|
| 11 |
+
Pygments==2.19.2
|
| 12 |
+
PySocks==1.7.1
|
| 13 |
+
pytest==8.4.2
|
| 14 |
+
pytest-dependency==0.6.0
|
| 15 |
+
selenium==4.36.0
|
| 16 |
+
setuptools==80.9.0
|
| 17 |
+
sniffio==1.3.1
|
| 18 |
+
sortedcontainers==2.4.0
|
| 19 |
+
tomli==2.3.0
|
| 20 |
+
trio==0.31.0
|
| 21 |
+
trio-websocket==0.12.2
|
| 22 |
+
typing_extensions==4.15.0
|
| 23 |
+
urllib3==2.5.0
|
| 24 |
+
websocket-client==1.9.0
|
| 25 |
+
wsproto==1.2.0
|
llama.cpp/scripts/snapdragon/qdc/tests/test_bench.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pytest
|
| 2 |
+
import subprocess
|
| 3 |
+
import sys
|
| 4 |
+
|
| 5 |
+
tmp_path='/data/local/tmp'
|
| 6 |
+
pkg_path=f'{tmp_path}/llama.cpp'
|
| 7 |
+
lib_path=f'{pkg_path}/lib'
|
| 8 |
+
bin_path=f'{pkg_path}/bin'
|
| 9 |
+
|
| 10 |
+
model='../gguf/Llama-3.2-1B-Instruct-Q4_0.gguf'
|
| 11 |
+
cli_pref=f'cd {pkg_path} && LD_LIBRARY_PATH={lib_path} ADSP_LIBRARY_PATH={lib_path} {bin_path}'
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def run_cmd(cmd):
|
| 15 |
+
p = subprocess.run(cmd, text = True, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
|
| 16 |
+
sys.stdout.write(p.stdout)
|
| 17 |
+
assert(p.returncode == 0)
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
@pytest.mark.dependency()
|
| 21 |
+
def test_install():
|
| 22 |
+
run_cmd(['adb', 'push', 'llama.cpp', f'{tmp_path}'])
|
| 23 |
+
run_cmd(['adb', 'shell', f'chmod 755 {bin_path}/*'])
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
## Basic cli tests
|
| 27 |
+
def run_llama_cli(dev, opts):
|
| 28 |
+
prompt='what is the most popular cookie in the world?\nPlease provide a very brief bullet point summary.\nBegin your answer with **BEGIN**.'
|
| 29 |
+
opts = '--batch-size 128 -n 128 -no-cnv --seed 42 ' + opts
|
| 30 |
+
run_cmd(['adb', 'shell', f'{cli_pref}/llama-cli -m {model} --device {dev} -ngl 99 -t 4 {opts} -p "{prompt}"'])
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
@pytest.mark.dependency(depends=['test_install'])
|
| 34 |
+
def test_llama_cli_cpu():
|
| 35 |
+
run_llama_cli('none', '-ctk q8_0 -ctv q8_0 -fa on')
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
@pytest.mark.dependency(depends=['test_install'])
|
| 39 |
+
def test_llama_cli_gpu():
|
| 40 |
+
run_llama_cli('GPUOpenCL', '-fa on')
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
@pytest.mark.dependency(depends=['test_install'])
|
| 44 |
+
def test_llama_cli_npu():
|
| 45 |
+
run_llama_cli('HTP0', '-ctk q8_0 -ctv q8_0 -fa on')
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
## Basic bench tests
|
| 49 |
+
def run_llama_bench(dev):
|
| 50 |
+
run_cmd(['adb', 'shell', f'{cli_pref}/llama-bench -m {model} --device {dev} -ngl 99 --batch-size 128 -t 4 -p 128 -n 32'])
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
@pytest.mark.dependency(depends=['test_install'])
|
| 54 |
+
def test_llama_bench_cpu():
|
| 55 |
+
run_llama_bench('none')
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def test_llama_bench_gpu():
|
| 59 |
+
run_llama_bench('GPUOpenCL')
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def test_llama_bench_npu():
|
| 63 |
+
run_llama_bench('HTP0')
|
llama.cpp/scripts/snapdragon/windows/run-bench.ps1
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
#!/usr/bin/env pwsh
|
| 3 |
+
|
| 4 |
+
# Basedir on device
|
| 5 |
+
$basedir=".\pkg-snapdragon"
|
| 6 |
+
|
| 7 |
+
$cli_opts=$args
|
| 8 |
+
|
| 9 |
+
$model="Llama-3.2-3B-Instruct-Q4_0.gguf"
|
| 10 |
+
if ($null -ne $env:M) {
|
| 11 |
+
$model=$env:M
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
$device="HTP0"
|
| 15 |
+
if ($null -ne $env:D) {
|
| 16 |
+
$device=$env:D
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
if ($null -ne $env:V) {
|
| 20 |
+
$env:GGML_HEXAGON_VERBOSE=$env:V
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
if ($null -ne $env:OPMASK) {
|
| 24 |
+
$env:GGML_HEXAGON_OPMASK=$env:OPMASK
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
if ($null -ne $env:NHVX) {
|
| 28 |
+
$env:GGML_HEXAGON_NHVX=$env:NHVX
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
if ($null -ne $env:NDEV) {
|
| 32 |
+
$env:GGML_HEXAGON_NDEV=$env:NDEV
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
$env:ADSP_LIBRARY_PATH="$basedir\lib"
|
| 36 |
+
|
| 37 |
+
& "$basedir\bin\llama-bench.exe" `
|
| 38 |
+
--mmap 0 -m $basedir\..\..\gguf\$model `
|
| 39 |
+
--poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 `
|
| 40 |
+
--batch-size 128 -ngl 99 --device $device $cli_opts
|
llama.cpp/scripts/snapdragon/windows/run-cli.ps1
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
#!/usr/bin/env pwsh
|
| 3 |
+
|
| 4 |
+
# Basedir on device
|
| 5 |
+
$basedir=".\pkg-snapdragon"
|
| 6 |
+
|
| 7 |
+
$cli_opts=$args
|
| 8 |
+
|
| 9 |
+
$model="Llama-3.2-3B-Instruct-Q4_0.gguf"
|
| 10 |
+
if ($null -ne $env:M) {
|
| 11 |
+
$model=$env:M
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
$device="HTP0"
|
| 15 |
+
if ($null -ne $env:D) {
|
| 16 |
+
$device=$env:D
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
if ($null -ne $env:V) {
|
| 20 |
+
$env:GGML_HEXAGON_VERBOSE=$env:V
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
if ($null -ne $env:E) {
|
| 24 |
+
$env:GGML_HEXAGON_EXPERIMENTAL=$env:E
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
if ($null -ne $env:SCHED) {
|
| 28 |
+
$env:GGML_SCHED_DEBUG=$env:SCHED; $cli_opts="$cli_opts -v"
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
if ($null -ne $env:PROF) {
|
| 32 |
+
$env:GGML_HEXAGON_PROFILE=$env:PROF; $env:GGML_HEXAGON_OPSYNC=1
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
if ($null -ne $env:OPMASK) {
|
| 36 |
+
$env:GGML_HEXAGON_OPMASK=$env:OPMASK
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
if ($null -ne $env:NHVX) {
|
| 40 |
+
$env:GGML_HEXAGON_NHVX=$env:NHVX
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
if ($null -ne $env:NDEV) {
|
| 44 |
+
$env:GGML_HEXAGON_NDEV=$env:NDEV
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
$env:ADSP_LIBRARY_PATH="$basedir\lib"
|
| 48 |
+
|
| 49 |
+
& "$basedir\bin\llama-completion.exe" `
|
| 50 |
+
--no-mmap -no-cnv -m $basedir\..\..\gguf\$model `
|
| 51 |
+
--poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 `
|
| 52 |
+
--ctx-size 8192 --ubatch-size 128 -fa on `
|
| 53 |
+
-ngl 99 --device $device $cli_opts
|
llama.cpp/scripts/snapdragon/windows/run-tool.ps1
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
#!/usr/bin/env pwsh
|
| 3 |
+
|
| 4 |
+
# Basedir on device
|
| 5 |
+
$basedir=".\pkg-snapdragon"
|
| 6 |
+
|
| 7 |
+
if ($args.Count -eq 0) {
|
| 8 |
+
Write-Host "No arguments provided.Expected the tool and argument to run."
|
| 9 |
+
exit -1
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
$tool=$args[0]
|
| 13 |
+
$cli_opts=@()
|
| 14 |
+
|
| 15 |
+
if ($args.Count -gt 1) {
|
| 16 |
+
$cli_opts=$args[1..($args.Count - 1)]
|
| 17 |
+
$remainingArgs = $args[1..($args.Count - 1)]
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
$device="HTP0"
|
| 21 |
+
if ($null -ne $env:D) {
|
| 22 |
+
$device=$env:D
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
if ($null -ne $env:V) {
|
| 26 |
+
$env:GGML_HEXAGON_VERBOSE=$env:V
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
if ($null -ne $env:E) {
|
| 30 |
+
$env:GGML_HEXAGON_EXPERIMENTAL=$env:E
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
if ($null -ne $env:SCHED) {
|
| 34 |
+
$env:GGML_SCHED_DEBUG=$env:SCHED; $cli_opts="$cli_opts -v"
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
if ($null -ne $env:PROF) {
|
| 38 |
+
$env:GGML_HEXAGON_PROFILE=$env:PROF; $env:GGML_HEXAGON_OPSYNC=1
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
if ($null -ne $env:OPMASK) {
|
| 42 |
+
$env:GGML_HEXAGON_OPMASK=$env:OPMASK
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
if ($null -ne $env:NHVX) {
|
| 46 |
+
$env:GGML_HEXAGON_NHVX=$env:NHVX
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
if ($null -ne $env:NDEV) {
|
| 50 |
+
$env:GGML_HEXAGON_NDEV=$env:NDEV
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
$env:ADSP_LIBRARY_PATH="$basedir\lib"
|
| 54 |
+
|
| 55 |
+
& "$basedir\bin\$tool" `
|
| 56 |
+
$cli_opts
|
llama.cpp/scripts/snapdragon/windows/setup-build.ps1
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Requires Run as Administrator is NOT strictly necessary for User-scope env vars,
|
| 2 |
+
# but recommended for creating directories in C:\ root if permissions are restricted.
|
| 3 |
+
|
| 4 |
+
$ErrorActionPreference = "Stop"
|
| 5 |
+
|
| 6 |
+
# --- Configuration ---
|
| 7 |
+
$BaseDir = "C:\Qualcomm"
|
| 8 |
+
|
| 9 |
+
# SDK 1: Hexagon
|
| 10 |
+
$HexagonUrl = "https://github.com/snapdragon-toolchain/hexagon-sdk/releases/download/v6.4.0.2/hexagon-sdk-v6.4.0.2-arm64-wos.tar.xz"
|
| 11 |
+
$HexagonParent = Join-Path $BaseDir "Hexagon_SDK"
|
| 12 |
+
$HexagonSdkVersion = "6.4.0.2"
|
| 13 |
+
$HexagonToolsVersion = "19.0.04"
|
| 14 |
+
$HexagonSdkTarget = Join-Path $HexagonParent $HexagonSdkVersion
|
| 15 |
+
$HexagonToolsTarget = Join-Path $HexagonSdkTarget "\tools\HEXAGON_Tools\$HexagonToolsVersion"
|
| 16 |
+
|
| 17 |
+
# SDK 2: OpenCL
|
| 18 |
+
$OpenCLUrl = "https://github.com/snapdragon-toolchain/opencl-sdk/releases/download/v2.3.2/adreno-opencl-sdk-v2.3.2-arm64-wos.tar.xz"
|
| 19 |
+
$OpenCLParent = Join-Path $BaseDir "OpenCL_SDK"
|
| 20 |
+
$OpenCLVersion = "2.3.2"
|
| 21 |
+
$OpenCLTarget = Join-Path $OpenCLParent $OpenCLVersion
|
| 22 |
+
|
| 23 |
+
# --- Helper Function ---
|
| 24 |
+
function Install-QualcommSDK {
|
| 25 |
+
param (
|
| 26 |
+
[string]$Url,
|
| 27 |
+
[string]$ParentDir,
|
| 28 |
+
[string]$TargetDir,
|
| 29 |
+
[string]$Name
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
# 1. Create Parent Directory
|
| 33 |
+
if (-not (Test-Path -Path $ParentDir)) {
|
| 34 |
+
Write-Host "Creating directory: $ParentDir" -ForegroundColor Cyan
|
| 35 |
+
New-Item -Path $ParentDir -ItemType Directory -Force | Out-Null
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
# 2. Check for Specific Version Directory
|
| 39 |
+
if (Test-Path -Path $TargetDir) {
|
| 40 |
+
Write-Host "$Name ($TargetDir) already exists. Skipping download." -ForegroundColor Green
|
| 41 |
+
}
|
| 42 |
+
else {
|
| 43 |
+
Write-Host "$Name not found. preparing to download..." -ForegroundColor Yellow
|
| 44 |
+
|
| 45 |
+
# Create the target directory to extract into
|
| 46 |
+
New-Item -Path $TargetDir -ItemType Directory -Force | Out-Null
|
| 47 |
+
|
| 48 |
+
# Define temporary archive path
|
| 49 |
+
$TempFile = Join-Path $ParentDir "temp_sdk.tar.xz"
|
| 50 |
+
|
| 51 |
+
try {
|
| 52 |
+
# Download
|
| 53 |
+
Write-Host "Downloading from: $Url"
|
| 54 |
+
Invoke-WebRequest -Uri $Url -OutFile $TempFile
|
| 55 |
+
|
| 56 |
+
# Untar
|
| 57 |
+
# Note: We assume Windows includes tar.exe (Win 10 build 17063+)
|
| 58 |
+
Write-Host "Extracting archive to $TargetDir..."
|
| 59 |
+
|
| 60 |
+
# We use -C to extract contents INTO the target directory created above
|
| 61 |
+
tar -xJvf $TempFile -C $TargetDir\..
|
| 62 |
+
|
| 63 |
+
Write-Host "Extraction complete." -ForegroundColor Green
|
| 64 |
+
}
|
| 65 |
+
catch {
|
| 66 |
+
Write-Error "Failed to download or extract $Name. Error: $_"
|
| 67 |
+
# Cleanup target dir if failed so script tries again next time
|
| 68 |
+
Remove-Item -Path $TargetDir -Recurse -Force -ErrorAction SilentlyContinue
|
| 69 |
+
}
|
| 70 |
+
finally {
|
| 71 |
+
# Cleanup Archive
|
| 72 |
+
if (Test-Path $TempFile) { Remove-Item $TempFile -Force }
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
# --- Execution ---
|
| 78 |
+
|
| 79 |
+
# 1. Ensure Base C:\Qualcomm exists
|
| 80 |
+
if (-not (Test-Path $BaseDir)) {
|
| 81 |
+
New-Item -Path $BaseDir -ItemType Directory -Force | Out-Null
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
# 2. Run Install Logic
|
| 85 |
+
Install-QualcommSDK -Url $HexagonUrl -ParentDir $HexagonParent -TargetDir $HexagonSdkTarget -Name "Hexagon SDK"
|
| 86 |
+
Install-QualcommSDK -Url $OpenCLUrl -ParentDir $OpenCLParent -TargetDir $OpenCLTarget -Name "OpenCL SDK"
|
| 87 |
+
|
| 88 |
+
# --- Environment Variables ---
|
| 89 |
+
|
| 90 |
+
Write-Host "`nSetting Environment Variables..." -ForegroundColor Cyan
|
| 91 |
+
|
| 92 |
+
# Set OPENCL_SDK_ROOT
|
| 93 |
+
[System.Environment]::SetEnvironmentVariable('OPENCL_SDK_ROOT', $OpenCLTarget, [System.EnvironmentVariableTarget]::User)
|
| 94 |
+
$env:OPENCL_SDK_ROOT = $OpenCLTarget # Set for current session as well
|
| 95 |
+
Write-Host "OPENCL_SDK_ROOT set to: $OpenCLTarget"
|
| 96 |
+
|
| 97 |
+
# Set HEXAGON_SDK_ROOT
|
| 98 |
+
[System.Environment]::SetEnvironmentVariable('HEXAGON_SDK_ROOT', $HexagonSdkTarget, [System.EnvironmentVariableTarget]::User)
|
| 99 |
+
$env:HEXAGON_SDK_ROOT = $HexagonSdkTarget # Set for current session as well
|
| 100 |
+
Write-Host "HEXAGON_SDK_ROOT set to: $HexagonSdkTarget"
|
| 101 |
+
|
| 102 |
+
# Set HEXAGON_SDK_ROOT
|
| 103 |
+
[System.Environment]::SetEnvironmentVariable('HEXAGON_TOOLS_ROOT', $HexagonToolsTarget, [System.EnvironmentVariableTarget]::User)
|
| 104 |
+
$env:HEXAGON_TOOLS_ROOT = $HexagonToolsTarget # Set for current session as well
|
| 105 |
+
Write-Host "HEXAGON_TOOLS_ROOT set to: $HexagonToolsTarget"
|
llama.cpp/src/models/afmoe.cpp
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "models.h"
|
| 2 |
+
|
| 3 |
+
llm_build_afmoe::llm_build_afmoe(const llama_model & model, const llm_graph_params & params) : llm_graph_context(params) {
|
| 4 |
+
const int64_t n_embd_head = hparams.n_embd_head_v;
|
| 5 |
+
GGML_ASSERT(n_embd_head == hparams.n_embd_head_k);
|
| 6 |
+
|
| 7 |
+
ggml_tensor * cur;
|
| 8 |
+
ggml_tensor * inpL;
|
| 9 |
+
|
| 10 |
+
inpL = build_inp_embd(model.tok_embd);
|
| 11 |
+
|
| 12 |
+
// MuP scaling: embeddings * sqrt(hidden_size)
|
| 13 |
+
// mup_enabled = true, hidden_size = 1024, scale = 32.0
|
| 14 |
+
inpL = ggml_scale(ctx0, inpL, sqrtf(float(n_embd)));
|
| 15 |
+
cb(inpL, "inp_embd_scaled", -1);
|
| 16 |
+
|
| 17 |
+
// inp_pos - contains the positions
|
| 18 |
+
ggml_tensor * inp_pos = build_inp_pos();
|
| 19 |
+
auto * inp_attn = build_attn_inp_kv_iswa();
|
| 20 |
+
ggml_tensor * inp_out_ids = build_inp_out_ids();
|
| 21 |
+
|
| 22 |
+
const float kq_scale = 1.0f/sqrtf(float(n_embd_head));
|
| 23 |
+
|
| 24 |
+
for (int il = 0; il < n_layer; ++il) {
|
| 25 |
+
const float freq_base_l = model.get_rope_freq_base (cparams, il);
|
| 26 |
+
const float freq_scale_l = model.get_rope_freq_scale(cparams, il);
|
| 27 |
+
|
| 28 |
+
ggml_tensor * inpSA = inpL;
|
| 29 |
+
|
| 30 |
+
// This overlaps with SWA layers in current models, so get_rope_freq_base/scale may be superfluous
|
| 31 |
+
const bool use_rope = hparams.n_no_rope_layer_step > 0 &&
|
| 32 |
+
(il + 1) % hparams.n_no_rope_layer_step != 0;
|
| 33 |
+
|
| 34 |
+
// dual attention normalization (pre)
|
| 35 |
+
cur = build_norm(inpL,
|
| 36 |
+
model.layers[il].attn_norm, NULL,
|
| 37 |
+
LLM_NORM_RMS, il);
|
| 38 |
+
cb(cur, "attn_norm", il);
|
| 39 |
+
|
| 40 |
+
// self-attention
|
| 41 |
+
{
|
| 42 |
+
ggml_tensor * attn_inp = cur; // save input for gate computation
|
| 43 |
+
|
| 44 |
+
ggml_tensor * Qcur = build_lora_mm(model.layers[il].wq, cur);
|
| 45 |
+
cb(Qcur, "Qcur", il);
|
| 46 |
+
|
| 47 |
+
ggml_tensor * Kcur = build_lora_mm(model.layers[il].wk, cur);
|
| 48 |
+
cb(Kcur, "Kcur", il);
|
| 49 |
+
|
| 50 |
+
ggml_tensor * Vcur = build_lora_mm(model.layers[il].wv, cur);
|
| 51 |
+
cb(Vcur, "Vcur", il);
|
| 52 |
+
|
| 53 |
+
// compute gate from input
|
| 54 |
+
ggml_tensor * gate = build_lora_mm(model.layers[il].wqkv_gate, attn_inp);
|
| 55 |
+
cb(gate, "attn_gate_proj", il);
|
| 56 |
+
|
| 57 |
+
Qcur = ggml_reshape_3d(ctx0, Qcur, n_embd_head, n_head, n_tokens);
|
| 58 |
+
Kcur = ggml_reshape_3d(ctx0, Kcur, n_embd_head, n_head_kv, n_tokens);
|
| 59 |
+
|
| 60 |
+
// Q/K normalization
|
| 61 |
+
Qcur = build_norm(Qcur, model.layers[il].attn_q_norm, NULL, LLM_NORM_RMS, il);
|
| 62 |
+
Kcur = build_norm(Kcur, model.layers[il].attn_k_norm, NULL, LLM_NORM_RMS, il);
|
| 63 |
+
cb(Qcur, "Qcur_normed", il);
|
| 64 |
+
cb(Kcur, "Kcur_normed", il);
|
| 65 |
+
|
| 66 |
+
if (use_rope) {
|
| 67 |
+
Qcur = ggml_rope_ext(
|
| 68 |
+
ctx0, Qcur, inp_pos, nullptr,
|
| 69 |
+
n_rot, rope_type, n_ctx_orig, freq_base_l, freq_scale_l,
|
| 70 |
+
ext_factor, attn_factor, beta_fast, beta_slow);
|
| 71 |
+
cb(Qcur, "Qcur_rope", il);
|
| 72 |
+
|
| 73 |
+
Kcur = ggml_rope_ext(
|
| 74 |
+
ctx0, Kcur, inp_pos, nullptr,
|
| 75 |
+
n_rot, rope_type, n_ctx_orig, freq_base_l, freq_scale_l,
|
| 76 |
+
ext_factor, attn_factor, beta_fast, beta_slow);
|
| 77 |
+
cb(Kcur, "Kcur_rope", il);
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
Vcur = ggml_reshape_3d(ctx0, Vcur, n_embd_head, n_head_kv, n_tokens);
|
| 81 |
+
|
| 82 |
+
cur = build_attn(inp_attn,
|
| 83 |
+
NULL, NULL, // wo will be applied after gating
|
| 84 |
+
Qcur, Kcur, Vcur, nullptr, nullptr, nullptr, kq_scale, il);
|
| 85 |
+
cb(cur, "attn_out", il);
|
| 86 |
+
|
| 87 |
+
// attention gating: attn_out * sigmoid(gate) BEFORE o_proj
|
| 88 |
+
gate = ggml_sigmoid(ctx0, gate);
|
| 89 |
+
cb(gate, "attn_gate_sig", il);
|
| 90 |
+
cur = ggml_mul(ctx0, cur, gate);
|
| 91 |
+
cb(cur, "attn_gated", il);
|
| 92 |
+
|
| 93 |
+
// now apply output projection
|
| 94 |
+
cur = build_lora_mm(model.layers[il].wo, cur);
|
| 95 |
+
cb(cur, "attn_o_proj", il);
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
// dual attention normalization (post)
|
| 99 |
+
cur = build_norm(cur,
|
| 100 |
+
model.layers[il].attn_post_norm, NULL,
|
| 101 |
+
LLM_NORM_RMS, il);
|
| 102 |
+
cb(cur, "attn_post_norm", il);
|
| 103 |
+
|
| 104 |
+
if (il == n_layer - 1 && inp_out_ids) {
|
| 105 |
+
cur = ggml_get_rows(ctx0, cur, inp_out_ids);
|
| 106 |
+
inpSA = ggml_get_rows(ctx0, inpSA, inp_out_ids);
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
ggml_tensor * ffn_inp = ggml_add(ctx0, cur, inpSA);
|
| 110 |
+
cb(ffn_inp, "ffn_inp", il);
|
| 111 |
+
|
| 112 |
+
// dual ffn normalization (pre)
|
| 113 |
+
cur = build_norm(ffn_inp,
|
| 114 |
+
model.layers[il].ffn_norm, NULL,
|
| 115 |
+
LLM_NORM_RMS, il);
|
| 116 |
+
cb(cur, "ffn_norm", il);
|
| 117 |
+
|
| 118 |
+
// MoE or dense FFN
|
| 119 |
+
if ((uint32_t)il >= hparams.n_layer_dense_lead) {
|
| 120 |
+
// MoE layer with sigmoid routing, normalization, and scaling
|
| 121 |
+
ggml_tensor * moe_out = build_moe_ffn(cur,
|
| 122 |
+
model.layers[il].ffn_gate_inp,
|
| 123 |
+
model.layers[il].ffn_up_exps,
|
| 124 |
+
model.layers[il].ffn_gate_exps,
|
| 125 |
+
model.layers[il].ffn_down_exps,
|
| 126 |
+
model.layers[il].ffn_exp_probs_b,
|
| 127 |
+
n_expert, n_expert_used,
|
| 128 |
+
LLM_FFN_SILU,
|
| 129 |
+
hparams.expert_weights_norm, // norm_w (route_norm=True)
|
| 130 |
+
hparams.expert_weights_scale, // scale_w
|
| 131 |
+
hparams.expert_weights_scale, // w_scale (route_scale=2.826)
|
| 132 |
+
(llama_expert_gating_func_type) hparams.expert_gating_func,
|
| 133 |
+
il);
|
| 134 |
+
cb(moe_out, "ffn_moe_out", il);
|
| 135 |
+
|
| 136 |
+
// shared expert
|
| 137 |
+
if (hparams.n_expert_shared > 0) {
|
| 138 |
+
ggml_tensor * ffn_shexp = build_ffn(cur,
|
| 139 |
+
model.layers[il].ffn_up_shexp, NULL, NULL,
|
| 140 |
+
model.layers[il].ffn_gate_shexp, NULL, NULL,
|
| 141 |
+
model.layers[il].ffn_down_shexp, NULL, NULL,
|
| 142 |
+
NULL,
|
| 143 |
+
LLM_FFN_SILU, LLM_FFN_PAR, il);
|
| 144 |
+
cb(ffn_shexp, "ffn_shexp", il);
|
| 145 |
+
|
| 146 |
+
cur = ggml_add(ctx0, moe_out, ffn_shexp);
|
| 147 |
+
cb(cur, "ffn_out", il);
|
| 148 |
+
} else {
|
| 149 |
+
cur = moe_out;
|
| 150 |
+
}
|
| 151 |
+
} else {
|
| 152 |
+
// dense layer
|
| 153 |
+
cur = build_ffn(cur,
|
| 154 |
+
model.layers[il].ffn_up, NULL, NULL,
|
| 155 |
+
model.layers[il].ffn_gate, NULL, NULL,
|
| 156 |
+
model.layers[il].ffn_down, NULL, NULL,
|
| 157 |
+
NULL,
|
| 158 |
+
LLM_FFN_SILU, LLM_FFN_PAR, il);
|
| 159 |
+
cb(cur, "ffn_out", il);
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
// dual ffn normalization (post)
|
| 163 |
+
cur = build_norm(cur,
|
| 164 |
+
model.layers[il].ffn_post_norm, NULL,
|
| 165 |
+
LLM_NORM_RMS, il);
|
| 166 |
+
cb(cur, "ffn_post_norm", il);
|
| 167 |
+
|
| 168 |
+
cur = ggml_add(ctx0, cur, ffn_inp);
|
| 169 |
+
cur = build_cvec(cur, il);
|
| 170 |
+
cb(cur, "l_out", il);
|
| 171 |
+
|
| 172 |
+
// input for next layer
|
| 173 |
+
inpL = cur;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
cur = inpL;
|
| 177 |
+
|
| 178 |
+
cur = build_norm(cur,
|
| 179 |
+
model.output_norm, NULL,
|
| 180 |
+
LLM_NORM_RMS, -1);
|
| 181 |
+
cb(cur, "result_norm", -1);
|
| 182 |
+
|
| 183 |
+
res->t_embd = cur;
|
| 184 |
+
|
| 185 |
+
// lm_head
|
| 186 |
+
cur = build_lora_mm(model.output, cur);
|
| 187 |
+
cb(cur, "result_output", -1);
|
| 188 |
+
res->t_logits = cur;
|
| 189 |
+
|
| 190 |
+
ggml_build_forward_expand(gf, cur);
|
| 191 |
+
}
|
llama.cpp/src/models/apertus.cpp
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "models.h"
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
llm_build_apertus::llm_build_apertus(const llama_model & model, const llm_graph_params & params) : llm_graph_context(params) {
|
| 6 |
+
const int64_t n_embd_head = hparams.n_embd_head_v;
|
| 7 |
+
|
| 8 |
+
GGML_ASSERT(n_embd_head == hparams.n_embd_head_k);
|
| 9 |
+
GGML_ASSERT(n_embd_head == hparams.n_rot);
|
| 10 |
+
|
| 11 |
+
ggml_tensor * cur;
|
| 12 |
+
ggml_tensor * inpL;
|
| 13 |
+
|
| 14 |
+
inpL = build_inp_embd(model.tok_embd);
|
| 15 |
+
|
| 16 |
+
ggml_tensor * inp_pos = build_inp_pos();
|
| 17 |
+
auto * inp_attn = build_attn_inp_kv();
|
| 18 |
+
|
| 19 |
+
const float kq_scale =
|
| 20 |
+
hparams.f_attention_scale == 0.0f ? 1.0f / sqrtf(float(n_embd_head)) : hparams.f_attention_scale;
|
| 21 |
+
|
| 22 |
+
ggml_tensor * inp_out_ids = build_inp_out_ids();
|
| 23 |
+
|
| 24 |
+
for (int il = 0; il < n_layer; ++il) {
|
| 25 |
+
ggml_tensor * inpSA = inpL;
|
| 26 |
+
|
| 27 |
+
cur = build_norm(inpL, model.layers[il].attn_norm, nullptr, LLM_NORM_RMS, il);
|
| 28 |
+
cb(cur, "attn_norm", il);
|
| 29 |
+
|
| 30 |
+
// self-attention
|
| 31 |
+
{
|
| 32 |
+
ggml_tensor * rope_factors = model.get_rope_factors(cparams, il);
|
| 33 |
+
|
| 34 |
+
// compute Q and K and RoPE them
|
| 35 |
+
ggml_tensor * Qcur = build_lora_mm(model.layers[il].wq, cur);
|
| 36 |
+
cb(Qcur, "Qcur", il);
|
| 37 |
+
|
| 38 |
+
ggml_tensor * Kcur = build_lora_mm(model.layers[il].wk, cur);
|
| 39 |
+
cb(Kcur, "Kcur", il);
|
| 40 |
+
|
| 41 |
+
ggml_tensor * Vcur = build_lora_mm(model.layers[il].wv, cur);
|
| 42 |
+
cb(Vcur, "Vcur", il);
|
| 43 |
+
|
| 44 |
+
Qcur = ggml_reshape_3d(ctx0, Qcur, n_embd_head, n_head, n_tokens);
|
| 45 |
+
Qcur = build_norm(Qcur, model.layers[il].attn_q_norm, NULL, LLM_NORM_RMS, il);
|
| 46 |
+
cb(Qcur, "Qcur_normed", il);
|
| 47 |
+
|
| 48 |
+
Kcur = ggml_reshape_3d(ctx0, Kcur, n_embd_head, n_head_kv, n_tokens);
|
| 49 |
+
Kcur = build_norm(Kcur, model.layers[il].attn_k_norm, NULL, LLM_NORM_RMS, il);
|
| 50 |
+
cb(Kcur, "Kcur_normed", il);
|
| 51 |
+
|
| 52 |
+
Vcur = ggml_reshape_3d(ctx0, Vcur, n_embd_head, n_head_kv, n_tokens);
|
| 53 |
+
|
| 54 |
+
Qcur = ggml_rope_ext(ctx0, Qcur, inp_pos, rope_factors, n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
|
| 55 |
+
ext_factor, attn_factor, beta_fast, beta_slow);
|
| 56 |
+
|
| 57 |
+
Kcur = ggml_rope_ext(ctx0, Kcur, inp_pos, rope_factors, n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
|
| 58 |
+
ext_factor, attn_factor, beta_fast, beta_slow);
|
| 59 |
+
|
| 60 |
+
cb(Qcur, "Qcur_pos", il);
|
| 61 |
+
cb(Kcur, "Kcur_pos", il);
|
| 62 |
+
cb(Vcur, "Vcur_pos", il);
|
| 63 |
+
|
| 64 |
+
cur = build_attn(inp_attn,
|
| 65 |
+
model.layers[il].wo, model.layers[il].bo,
|
| 66 |
+
Qcur, Kcur, Vcur, nullptr, nullptr, nullptr, kq_scale, il);
|
| 67 |
+
cb(cur, "attn_out", il);
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
if (il == n_layer - 1 && inp_out_ids) {
|
| 71 |
+
cur = ggml_get_rows(ctx0, cur, inp_out_ids);
|
| 72 |
+
inpSA = ggml_get_rows(ctx0, inpSA, inp_out_ids);
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
ggml_tensor * ffn_inp = ggml_add(ctx0, cur, inpSA);
|
| 76 |
+
cb(ffn_inp, "ffn_inp", il);
|
| 77 |
+
|
| 78 |
+
// feed-forward network with xIELU activation
|
| 79 |
+
{
|
| 80 |
+
cur = build_norm(ffn_inp, model.layers[il].ffn_norm, nullptr, LLM_NORM_RMS, il);
|
| 81 |
+
cb(cur, "ffn_norm", il);
|
| 82 |
+
|
| 83 |
+
// Up projection
|
| 84 |
+
ggml_tensor * up = build_lora_mm(model.layers[il].ffn_up, cur);
|
| 85 |
+
cb(up, "ffn_up", il);
|
| 86 |
+
|
| 87 |
+
float alpha_n_val = hparams.xielu_alpha_n[il];
|
| 88 |
+
float alpha_p_val = hparams.xielu_alpha_p[il];
|
| 89 |
+
float beta_val = hparams.xielu_beta[il];
|
| 90 |
+
float eps_val = hparams.xielu_eps[il];
|
| 91 |
+
|
| 92 |
+
// Apply xIELU activation
|
| 93 |
+
ggml_tensor * activated = ggml_xielu(ctx0, up, alpha_n_val, alpha_p_val, beta_val, eps_val);
|
| 94 |
+
cb(activated, "ffn_xielu", il);
|
| 95 |
+
|
| 96 |
+
// Down projection
|
| 97 |
+
cur = build_lora_mm(model.layers[il].ffn_down, activated);
|
| 98 |
+
cb(cur, "ffn_down", il);
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
cur = ggml_add(ctx0, cur, ffn_inp);
|
| 102 |
+
cb(cur, "ffn_out", il);
|
| 103 |
+
|
| 104 |
+
cur = build_cvec(cur, il);
|
| 105 |
+
cb(cur, "l_out", il);
|
| 106 |
+
|
| 107 |
+
// input for next layer
|
| 108 |
+
inpL = cur;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
cur = inpL;
|
| 112 |
+
|
| 113 |
+
cur = build_norm(cur, model.output_norm, nullptr, LLM_NORM_RMS, -1);
|
| 114 |
+
|
| 115 |
+
cb(cur, "result_norm", -1);
|
| 116 |
+
res->t_embd = cur;
|
| 117 |
+
|
| 118 |
+
// lm_head
|
| 119 |
+
cur = build_lora_mm(model.output, cur);
|
| 120 |
+
|
| 121 |
+
cb(cur, "result_output", -1);
|
| 122 |
+
res->t_logits = cur;
|
| 123 |
+
|
| 124 |
+
ggml_build_forward_expand(gf, cur);
|
| 125 |
+
}
|