102 lines
3.7 KiB
PHP
102 lines
3.7 KiB
PHP
<?php
|
|
|
|
require_once __DIR__."/lib/index.php";
|
|
$debug_level = 0;
|
|
|
|
function LlamaCli(string|array $prompt, string $system = "You are a helpful assistant", array $options = []) {
|
|
|
|
//
|
|
// ---- 0. OPTIONS (Default and provided) -----
|
|
//
|
|
global $debug_level;
|
|
|
|
// Get the options passed
|
|
extract($options);
|
|
|
|
// Set defaults for what was not explicitly specified
|
|
|
|
$llamacpp_bin = $llamacpp_bin ?? "/home/frederico/llama.cpp/build/bin/llama-cli";
|
|
$llamacpp_model_path = $llamacpp_model_path ?? "/home/frederico/llama.cpp/models";
|
|
$llamacpp_model = $llamacpp_model ?? "Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf";
|
|
|
|
$parseCodeInOutput = $parseCodeInOutput ?? true;
|
|
$previousConversation = $previousConversation ?? []; // expects: [["role"=>"assistant","content"=>"How can I help you?"],["role"=>"user","content"=>"Tell me the capital of France"]]
|
|
$debug_level = $debug_level ?? 0;
|
|
|
|
$context_size = $context_size ?? 4096;
|
|
|
|
//
|
|
// ---- 1. INPUT TO LLM (DSL: adjustments needed) -----
|
|
//
|
|
|
|
// 1.1 Parse the prompt and resolve actions "@"
|
|
//if (is_array($prompt)) foreach($prompt as $i => $chunk) $prompt[$i] = ExpandFetcherCommands($chunk);
|
|
//else
|
|
$prompt = ExpandFetcherCommands($prompt);
|
|
|
|
// 1.2 Parse expanders / compressors
|
|
while(ParseExpandersIteratorsCompressors($prompt, "input",$options)) { }
|
|
|
|
if (is_array($prompt)) die("ERROR: at LLM stage, prompt is an array. Use '>(json|new-line)' compressor.");
|
|
|
|
|
|
// $llm_stdin = $prompt;
|
|
// Llama chat template
|
|
$llm_stdin = "<|start_header_id|>system<|end_header_id|>$system<|eot_id|>";
|
|
foreach($previousConversation as $message)
|
|
$llm_stdin .= "<|start_header_id|>{$message["role"]}<|end_header_id|>{$message["content"]}<|eot_id|>";
|
|
$llm_stdin .= "<|start_header_id|>user<|end_header_id|>$prompt<|eot_id|>";
|
|
$llm_stdin .= "<|start_header_id|>assistant<|end_header_id|>";
|
|
|
|
// Create a unique temporary file for STDIN, input data
|
|
$input_file_name = tempnam(sys_get_temp_dir(), 'tmp_');
|
|
if ($debug_level >= 4) file_put_contents("php://stderr","input_file_name $input_file_name content: $llm_stdin\n");
|
|
file_put_contents($input_file_name, $llm_stdin);
|
|
|
|
// Create a unique temporary file for STDERR, debug data
|
|
$debug_file_name = tempnam(sys_get_temp_dir(), 'tmp_');
|
|
if ($debug_file_name === false) die("Could not create temporary file\n");
|
|
|
|
|
|
$command = "$llamacpp_bin \
|
|
-m $llamacpp_model_path/$llamacpp_model \
|
|
-f $input_file_name \
|
|
-c $context_size \
|
|
-no-cnv \
|
|
--simple-io \
|
|
2> $debug_file_name ";
|
|
if ($debug_level >= 3) file_put_contents("php://stderr","Attempting command: $command\n");
|
|
$output = shell_exec($command);
|
|
|
|
|
|
// Save the DEBUG data from the LLM
|
|
$debug_data = file_get_contents($debug_file_name);
|
|
if ($debug_level >= 5) file_put_contents("php://stderr","debug_file_name $debug_file_name content: $debug_data\n");
|
|
|
|
// Clean TEMP files
|
|
if (file_exists($debug_file_name)) unlink($debug_file_name);
|
|
if (file_exists($input_file_name)) unlink($input_file_name);
|
|
|
|
//
|
|
// 5. Erase the input from the output
|
|
//
|
|
|
|
// 5.1 Llama specific model. produces in this format:
|
|
$output = str_replace("system$system", "", $output);
|
|
$output = str_replace("user$prompt"."assistant", "", $output);
|
|
foreach($previousConversation as $message)
|
|
$output = str_replace($message["role"].$message["content"],"",$output);
|
|
$output = str_replace("[end of text]", "", $output);
|
|
// 5.2 Generic input
|
|
//$output = str_replace($llm_stdin, "", $output);
|
|
// 5.3 Sanitize output
|
|
$output = trim($output);
|
|
if ($parseCodeInOutput)
|
|
$output = ExtractCodeSections($output);
|
|
|
|
|
|
return $output;
|
|
}
|
|
|
|
function LlamaCli_raw(string $prompt, string $system = "You are a helpful assistant", array $options = []) { $options["parseCodeInOutput"] = false; return LlamaCli($prompt, $system,$options); }
|