2024-09-09 23:36:09 +02:00
#include "arg.h"
2025-05-30 16:25:45 +03:00
#include "chat.h"
2025-04-02 14:52:01 +02:00
#include "common.h"
2025-05-30 16:25:45 +03:00
#include "gguf.h" // for reading GGUF splits
#include "json-schema-to-grammar.h"
2024-09-15 20:46:12 +03:00
#include "log.h"
2024-09-09 23:36:09 +02:00
#include "sampling.h"
2025-04-01 23:44:05 +02:00
// fix problem with std::min and std::max
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#ifndef NOMINMAX
# define NOMINMAX
#endif
#include <windows.h>
#endif
2025-05-30 16:25:45 +03:00
#define JSON_ASSERT GGML_ASSERT
#include <nlohmann/json.hpp>
2024-09-09 23:36:09 +02:00
#include <algorithm>
2024-09-15 20:46:12 +03:00
#include <climits>
#include <cstdarg>
2025-04-05 23:46:00 +08:00
#include <filesystem>
2024-09-09 23:36:09 +02:00
#include <fstream>
2025-09-22 14:13:51 +02:00
#include <future>
2025-08-04 16:05:36 -07:00
#include <list>
2024-09-09 23:36:09 +02:00
#include <regex>
2024-09-15 20:46:12 +03:00
#include <set>
#include <string>
#include <thread>
#include <vector>
2024-09-09 23:36:09 +02:00
2025-04-01 23:44:05 +02:00
#if defined(LLAMA_USE_CURL)
#include <curl/curl.h>
#include <curl/easy.h>
2025-09-26 13:12:19 +02:00
#else
2025-10-01 19:22:18 +02:00
#include "http.h"
2025-04-01 23:44:05 +02:00
#endif
2025-09-22 14:13:51 +02:00
#ifdef __linux__
#include <linux/limits.h>
#elif defined(_WIN32)
# if !defined(PATH_MAX)
# define PATH_MAX MAX_PATH
# endif
#elif defined(_AIX)
#include <sys/limits.h>
#else
#include <sys/syslimits.h>
#endif
#define LLAMA_MAX_URL_LENGTH 2084 // Maximum URL Length in Chrome: 2083
2025-09-30 19:52:41 +02:00
// isatty
#if defined(_WIN32)
#include <io.h>
#else
#include <unistd.h>
#endif
2024-09-09 23:36:09 +02:00
using json = nlohmann :: ordered_json ;
2025-04-24 12:14:13 +02:00
std :: initializer_list < enum llama_example > mmproj_examples = {
2025-05-22 20:42:48 +02:00
LLAMA_EXAMPLE_MTMD ,
2025-05-09 19:29:37 +02:00
LLAMA_EXAMPLE_SERVER ,
2025-04-24 12:14:13 +02:00
};
2025-04-30 10:46:32 +02:00
static std :: string read_file ( const std :: string & fname ) {
std :: ifstream file ( fname );
if ( ! file ) {
throw std :: runtime_error ( string_format ( "error: failed to open file '%s' \n " , fname . c_str ()));
}
std :: string content (( std :: istreambuf_iterator < char > ( file )), std :: istreambuf_iterator < char > ());
file . close ();
return content ;
}
static void write_file ( const std :: string & fname , const std :: string & content ) {
2025-09-18 16:22:50 +01:00
const std :: string fname_tmp = fname + ".tmp" ;
std :: ofstream file ( fname_tmp );
2025-04-30 10:46:32 +02:00
if ( ! file ) {
throw std :: runtime_error ( string_format ( "error: failed to open file '%s' \n " , fname . c_str ()));
}
2025-09-18 16:22:50 +01:00
try {
file << content ;
file . close ();
// Makes write atomic
if ( rename ( fname_tmp . c_str (), fname . c_str ()) != 0 ) {
LOG_ERR ( "%s: unable to rename file: %s to %s \n " , __func__ , fname_tmp . c_str (), fname . c_str ());
// If rename fails, try to delete the temporary file
if ( remove ( fname_tmp . c_str ()) != 0 ) {
LOG_ERR ( "%s: unable to delete temporary file: %s \n " , __func__ , fname_tmp . c_str ());
}
}
} catch (...) {
// If anything fails, try to delete the temporary file
if ( remove ( fname_tmp . c_str ()) != 0 ) {
LOG_ERR ( "%s: unable to delete temporary file: %s \n " , __func__ , fname_tmp . c_str ());
}
throw std :: runtime_error ( string_format ( "error: failed to write file '%s' \n " , fname . c_str ()));
}
2025-04-30 10:46:32 +02:00
}
2025-09-30 19:52:41 +02:00
static bool is_output_a_tty () {
#if defined(_WIN32)
return _isatty ( _fileno ( stdout ));
#else
return isatty ( 1 );
#endif
}
2024-10-10 22:57:42 +02:00
common_arg & common_arg :: set_examples ( std :: initializer_list < enum llama_example > examples ) {
2024-09-09 23:36:09 +02:00
this -> examples = std :: move ( examples );
return * this ;
}
2025-01-08 12:55:36 +02:00
common_arg & common_arg :: set_excludes ( std :: initializer_list < enum llama_example > excludes ) {
this -> excludes = std :: move ( excludes );
return * this ;
}
2024-10-10 22:57:42 +02:00
common_arg & common_arg :: set_env ( const char * env ) {
2024-09-09 23:36:09 +02:00
help = help + " \n (env: " + env + ")" ;
this -> env = env ;
return * this ;
}
2024-10-10 22:57:42 +02:00
common_arg & common_arg :: set_sparam () {
2024-09-09 23:36:09 +02:00
is_sparam = true ;
return * this ;
}
2024-10-10 22:57:42 +02:00
bool common_arg :: in_example ( enum llama_example ex ) {
2024-09-09 23:36:09 +02:00
return examples . find ( ex ) != examples . end ();
}
2025-01-08 12:55:36 +02:00
bool common_arg :: is_exclude ( enum llama_example ex ) {
return excludes . find ( ex ) != excludes . end ();
}
2024-10-10 22:57:42 +02:00
bool common_arg :: get_value_from_env ( std :: string & output ) {
2024-09-09 23:36:09 +02:00
if ( env == nullptr ) return false ;
char * value = std :: getenv ( env );
if ( value ) {
output = value ;
return true ;
}
return false ;
}
2024-10-10 22:57:42 +02:00
bool common_arg :: has_value_from_env () {
2024-09-09 23:36:09 +02:00
return env != nullptr && std :: getenv ( env );
}
static std :: vector < std :: string > break_str_into_lines ( std :: string input , size_t max_char_per_line ) {
std :: vector < std :: string > result ;
std :: istringstream iss ( input );
std :: string line ;
auto add_line = [ & ]( const std :: string & l ) {
if ( l . length () <= max_char_per_line ) {
result . push_back ( l );
} else {
std :: istringstream line_stream ( l );
std :: string word , current_line ;
while ( line_stream >> word ) {
if ( current_line . length () + ! current_line . empty () + word . length () > max_char_per_line ) {
if ( ! current_line . empty ()) result . push_back ( current_line );
current_line = word ;
} else {
current_line += ( ! current_line . empty () ? " " : "" ) + word ;
}
}
if ( ! current_line . empty ()) result . push_back ( current_line );
}
};
while ( std :: getline ( iss , line )) {
add_line ( line );
}
return result ;
}
2024-10-10 22:57:42 +02:00
std :: string common_arg :: to_string () {
2024-09-09 23:36:09 +02:00
// params for printing to console
const static int n_leading_spaces = 40 ;
const static int n_char_per_line_help = 70 ; // TODO: detect this based on current console
std :: string leading_spaces ( n_leading_spaces , ' ' );
std :: ostringstream ss ;
for ( const auto arg : args ) {
if ( arg == args . front ()) {
if ( args . size () == 1 ) {
ss << arg ;
} else {
// first arg is usually abbreviation, we need padding to make it more beautiful
auto tmp = std :: string ( arg ) + ", " ;
auto spaces = std :: string ( std :: max ( 0 , 7 - ( int ) tmp . size ()), ' ' );
ss << tmp << spaces ;
}
} else {
ss << arg << ( arg != args . back () ? ", " : "" );
}
}
if ( value_hint ) ss << " " << value_hint ;
if ( value_hint_2 ) ss << " " << value_hint_2 ;
if ( ss . tellp () > n_leading_spaces - 3 ) {
// current line is too long, add new line
ss << " \n " << leading_spaces ;
} else {
// padding between arg and help, same line
ss << std :: string ( leading_spaces . size () - ss . tellp (), ' ' );
}
const auto help_lines = break_str_into_lines ( help , n_char_per_line_help );
for ( const auto & line : help_lines ) {
ss << ( & line == & help_lines . front () ? "" : leading_spaces ) << line << " \n " ;
}
return ss . str ();
}
2025-04-01 23:44:05 +02:00
//
// downloader
//
struct common_hf_file_res {
std :: string repo ; // repo name with ":tag" removed
std :: string ggufFile ;
std :: string mmprojFile ;
};
2025-09-30 09:36:33 +02:00
static void write_etag ( const std :: string & path , const std :: string & etag ) {
const std :: string etag_path = path + ".etag" ;
write_file ( etag_path , etag );
LOG_DBG ( "%s: file etag saved: %s \n " , __func__ , etag_path . c_str ());
}
static std :: string read_etag ( const std :: string & path ) {
std :: string none ;
const std :: string etag_path = path + ".etag" ;
if ( std :: filesystem :: exists ( etag_path )) {
std :: ifstream etag_in ( etag_path );
if ( ! etag_in ) {
LOG_ERR ( "%s: could not open .etag file for reading: %s \n " , __func__ , etag_path . c_str ());
return none ;
}
std :: string etag ;
std :: getline ( etag_in , etag );
return etag ;
}
// no etag file, but maybe there is an old .json
// remove this code later
const std :: string metadata_path = path + ".json" ;
if ( std :: filesystem :: exists ( metadata_path )) {
std :: ifstream metadata_in ( metadata_path );
try {
nlohmann :: json metadata_json ;
metadata_in >> metadata_json ;
LOG_DBG ( "%s: previous metadata file found %s: %s \n " , __func__ , metadata_path . c_str (),
metadata_json . dump (). c_str ());
if ( metadata_json . contains ( "etag" ) && metadata_json . at ( "etag" ). is_string ()) {
std :: string etag = metadata_json . at ( "etag" );
write_etag ( path , etag );
if ( ! std :: filesystem :: remove ( metadata_path )) {
LOG_WRN ( "%s: failed to delete old .json metadata file: %s \n " , __func__ , metadata_path . c_str ());
}
return etag ;
}
} catch ( const nlohmann :: json :: exception & e ) {
LOG_ERR ( "%s: error reading metadata file %s: %s \n " , __func__ , metadata_path . c_str (), e . what ());
}
}
return none ;
}
2025-04-01 23:44:05 +02:00
#ifdef LLAMA_USE_CURL
//
// CURL utils
//
using curl_ptr = std :: unique_ptr < CURL , decltype ( & curl_easy_cleanup ) > ;
// cannot use unique_ptr for curl_slist, because we cannot update without destroying the old one
struct curl_slist_ptr {
struct curl_slist * ptr = nullptr ;
~ curl_slist_ptr () {
if ( ptr ) {
curl_slist_free_all ( ptr );
}
}
};
2025-09-18 16:22:50 +01:00
static CURLcode common_curl_perf ( CURL * curl ) {
CURLcode res = curl_easy_perform ( curl );
if ( res != CURLE_OK ) {
LOG_ERR ( "%s: curl_easy_perform() failed \n " , __func__ );
2025-04-01 23:44:05 +02:00
}
2025-09-18 16:22:50 +01:00
return res ;
2025-04-01 23:44:05 +02:00
}
2025-09-18 16:22:50 +01:00
// Send a HEAD request to retrieve the etag and last-modified headers
struct common_load_model_from_url_headers {
2025-05-26 14:34:27 -07:00
std :: string etag ;
std :: string last_modified ;
2025-09-18 16:22:50 +01:00
std :: string accept_ranges ;
};
2025-05-26 14:34:27 -07:00
2025-09-18 16:22:50 +01:00
struct FILE_deleter {
void operator ()( FILE * f ) const { fclose ( f ); }
};
static size_t common_header_callback ( char * buffer , size_t , size_t n_items , void * userdata ) {
common_load_model_from_url_headers * headers = ( common_load_model_from_url_headers * ) userdata ;
static std :: regex header_regex ( "([^:]+): (.*) \r\n " );
static std :: regex etag_regex ( "ETag" , std :: regex_constants :: icase );
static std :: regex last_modified_regex ( "Last-Modified" , std :: regex_constants :: icase );
static std :: regex accept_ranges_regex ( "Accept-Ranges" , std :: regex_constants :: icase );
std :: string header ( buffer , n_items );
std :: smatch match ;
if ( std :: regex_match ( header , match , header_regex )) {
const std :: string & key = match [ 1 ];
const std :: string & value = match [ 2 ];
if ( std :: regex_match ( key , match , etag_regex )) {
headers -> etag = value ;
} else if ( std :: regex_match ( key , match , last_modified_regex )) {
headers -> last_modified = value ;
} else if ( std :: regex_match ( key , match , accept_ranges_regex )) {
headers -> accept_ranges = value ;
2025-05-26 14:34:27 -07:00
}
}
2025-09-18 16:22:50 +01:00
return n_items ;
}
2025-05-26 14:34:27 -07:00
2025-09-18 16:22:50 +01:00
static size_t common_write_callback ( void * data , size_t size , size_t nmemb , void * fd ) {
return std :: fwrite ( data , size , nmemb , static_cast < FILE *> ( fd ));
}
2025-05-26 14:34:27 -07:00
2025-09-18 16:22:50 +01:00
// helper function to hide password in URL
static std :: string llama_download_hide_password_in_url ( const std :: string & url ) {
// Use regex to match and replace the user[:password]@ pattern in URLs
// Pattern: scheme://[user[:password]@]host[...]
static const std :: regex url_regex ( R "(^(?:[A-Za-z][A-Za-z0-9+.-]://)(?:[^/@]+@)?.$)" );
std :: smatch match ;
if ( std :: regex_match ( url , match , url_regex )) {
// match[1] = scheme (e.g., "https://")
// match[2] = user[:password]@ part
// match[3] = rest of URL (host and path)
return match [ 1 ]. str () + "********@" + match [ 3 ]. str ();
}
return url ; // No credentials found or malformed URL
}
static void common_curl_easy_setopt_head ( CURL * curl , const std :: string & url ) {
// Set the URL, allow to follow http redirection
curl_easy_setopt ( curl , CURLOPT_URL , url . c_str ());
curl_easy_setopt ( curl , CURLOPT_FOLLOWLOCATION , 1L );
# if defined(_WIN32)
// CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of
// operating system. Currently implemented under MS-Windows.
curl_easy_setopt ( curl , CURLOPT_SSL_OPTIONS , CURLSSLOPT_NATIVE_CA );
# endif
curl_easy_setopt ( curl , CURLOPT_NOBODY , 1L ); // will trigger the HEAD verb
curl_easy_setopt ( curl , CURLOPT_NOPROGRESS , 1L ); // hide head request progress
curl_easy_setopt ( curl , CURLOPT_HEADERFUNCTION , common_header_callback );
}
static void common_curl_easy_setopt_get ( CURL * curl ) {
curl_easy_setopt ( curl , CURLOPT_NOBODY , 0L );
curl_easy_setopt ( curl , CURLOPT_WRITEFUNCTION , common_write_callback );
// display download progress
curl_easy_setopt ( curl , CURLOPT_NOPROGRESS , 0L );
}
static bool common_pull_file ( CURL * curl , const std :: string & path_temporary ) {
if ( std :: filesystem :: exists ( path_temporary )) {
const std :: string partial_size = std :: to_string ( std :: filesystem :: file_size ( path_temporary ));
LOG_INF ( "%s: server supports range requests, resuming download from byte %s \n " , __func__ , partial_size . c_str ());
const std :: string range_str = partial_size + "-" ;
curl_easy_setopt ( curl , CURLOPT_RANGE , range_str . c_str ());
}
// Always open file in append mode could be resuming
std :: unique_ptr < FILE , FILE_deleter > outfile ( fopen ( path_temporary . c_str (), "ab" ));
if ( ! outfile ) {
LOG_ERR ( "%s: error opening local file for writing: %s \n " , __func__ , path_temporary . c_str ());
return false ;
}
common_curl_easy_setopt_get ( curl );
curl_easy_setopt ( curl , CURLOPT_WRITEDATA , outfile . get ());
return common_curl_perf ( curl ) == CURLE_OK ;
}
static bool common_download_head ( CURL * curl ,
curl_slist_ptr & http_headers ,
const std :: string & url ,
const std :: string & bearer_token ) {
2025-04-01 23:44:05 +02:00
if ( ! curl ) {
LOG_ERR ( "%s: error initializing libcurl \n " , __func__ );
return false ;
}
2025-04-11 20:01:56 +08:00
http_headers . ptr = curl_slist_append ( http_headers . ptr , "User-Agent: llama-cpp" );
2025-04-01 23:44:05 +02:00
// Check if hf-token or bearer-token was specified
if ( ! bearer_token . empty ()) {
std :: string auth_header = "Authorization: Bearer " + bearer_token ;
2025-09-18 16:22:50 +01:00
http_headers . ptr = curl_slist_append ( http_headers . ptr , auth_header . c_str ());
2025-05-26 14:34:27 -07:00
}
2025-04-01 23:44:05 +02:00
2025-09-18 16:22:50 +01:00
curl_easy_setopt ( curl , CURLOPT_HTTPHEADER , http_headers . ptr );
common_curl_easy_setopt_head ( curl , url );
return common_curl_perf ( curl ) == CURLE_OK ;
}
2025-04-01 23:44:05 +02:00
2025-09-18 16:22:50 +01:00
// download one single file from remote URL to local path
2025-09-22 14:13:51 +02:00
static bool common_download_file_single_online ( const std :: string & url ,
const std :: string & path ,
const std :: string & bearer_token ) {
2025-09-18 16:22:50 +01:00
static const int max_attempts = 3 ;
static const int retry_delay_seconds = 2 ;
for ( int i = 0 ; i < max_attempts ; ++ i ) {
2025-09-30 09:36:33 +02:00
std :: string etag ;
2025-04-30 10:46:32 +02:00
2025-09-18 16:22:50 +01:00
// Check if the file already exists locally
const auto file_exists = std :: filesystem :: exists ( path );
2025-04-01 23:44:05 +02:00
if ( file_exists ) {
2025-09-30 09:36:33 +02:00
etag = read_etag ( path );
2025-09-18 16:22:50 +01:00
} else {
LOG_INF ( "%s: no previous model file found %s \n " , __func__ , path . c_str ());
2025-04-01 23:44:05 +02:00
}
2025-09-18 16:22:50 +01:00
bool head_request_ok = false ;
bool should_download = ! file_exists ; // by default, we should download if the file does not exist
2025-04-01 23:44:05 +02:00
2025-09-18 16:22:50 +01:00
// Initialize libcurl
curl_ptr curl ( curl_easy_init (), & curl_easy_cleanup );
common_load_model_from_url_headers headers ;
curl_easy_setopt ( curl . get (), CURLOPT_HEADERDATA , & headers );
curl_slist_ptr http_headers ;
const bool was_perform_successful = common_download_head ( curl . get (), http_headers , url , bearer_token );
2025-04-01 23:44:05 +02:00
if ( ! was_perform_successful ) {
2025-09-18 16:22:50 +01:00
head_request_ok = false ;
2025-04-01 23:44:05 +02:00
}
long http_code = 0 ;
2025-09-18 16:22:50 +01:00
curl_easy_getinfo ( curl . get (), CURLINFO_RESPONSE_CODE , & http_code );
if ( http_code == 200 ) {
head_request_ok = true ;
} else {
LOG_WRN ( "%s: HEAD invalid http status code received: %ld \n " , __func__ , http_code );
head_request_ok = false ;
2025-04-01 23:44:05 +02:00
}
2025-09-18 16:22:50 +01:00
// if head_request_ok is false, we don't have the etag or last-modified headers
// we leave should_download as-is, which is true if the file does not exist
bool should_download_from_scratch = false ;
if ( head_request_ok ) {
// check if ETag or Last-Modified headers are different
// if it is, we need to download the file again
if ( ! etag . empty () && etag != headers . etag ) {
LOG_WRN ( "%s: ETag header is different (%s != %s): triggering a new download \n " , __func__ , etag . c_str (),
headers . etag . c_str ());
should_download = true ;
should_download_from_scratch = true ;
}
2025-04-01 23:44:05 +02:00
}
2025-09-18 16:22:50 +01:00
const bool accept_ranges_supported = ! headers . accept_ranges . empty () && headers . accept_ranges != "none" ;
if ( should_download ) {
if ( file_exists &&
! accept_ranges_supported ) { // Resumable downloads not supported, delete and start again.
LOG_WRN ( "%s: deleting previous downloaded file: %s \n " , __func__ , path . c_str ());
if ( remove ( path . c_str ()) != 0 ) {
LOG_ERR ( "%s: unable to delete file: %s \n " , __func__ , path . c_str ());
return false ;
}
}
const std :: string path_temporary = path + ".downloadInProgress" ;
if ( should_download_from_scratch ) {
if ( std :: filesystem :: exists ( path_temporary )) {
if ( remove ( path_temporary . c_str ()) != 0 ) {
LOG_ERR ( "%s: unable to delete file: %s \n " , __func__ , path_temporary . c_str ());
return false ;
}
}
if ( std :: filesystem :: exists ( path )) {
if ( remove ( path . c_str ()) != 0 ) {
LOG_ERR ( "%s: unable to delete file: %s \n " , __func__ , path . c_str ());
return false ;
}
}
}
2025-09-30 09:36:33 +02:00
if ( head_request_ok ) {
write_etag ( path , headers . etag );
}
2025-09-18 16:22:50 +01:00
// start the download
LOG_INF ( "%s: trying to download model from %s to %s (server_etag:%s, server_last_modified:%s)... \n " ,
__func__ , llama_download_hide_password_in_url ( url ). c_str (), path_temporary . c_str (),
headers . etag . c_str (), headers . last_modified . c_str ());
const bool was_pull_successful = common_pull_file ( curl . get (), path_temporary );
if ( ! was_pull_successful ) {
if ( i + 1 < max_attempts ) {
const int exponential_backoff_delay = std :: pow ( retry_delay_seconds , i ) * 1000 ;
LOG_WRN ( "%s: retrying after %d milliseconds... \n " , __func__ , exponential_backoff_delay );
std :: this_thread :: sleep_for ( std :: chrono :: milliseconds ( exponential_backoff_delay ));
} else {
LOG_ERR ( "%s: curl_easy_perform() failed after %d attempts \n " , __func__ , max_attempts );
}
continue ;
}
long http_code = 0 ;
curl_easy_getinfo ( curl . get (), CURLINFO_RESPONSE_CODE , & http_code );
if ( http_code < 200 || http_code >= 400 ) {
LOG_ERR ( "%s: invalid http status code received: %ld \n " , __func__ , http_code );
return false ;
}
if ( rename ( path_temporary . c_str (), path . c_str ()) != 0 ) {
LOG_ERR ( "%s: unable to rename file: %s to %s \n " , __func__ , path_temporary . c_str (), path . c_str ());
return false ;
}
} else {
LOG_INF ( "%s: using cached file: %s \n " , __func__ , path . c_str ());
}
break ;
2025-04-01 23:44:05 +02:00
}
return true ;
}
2025-09-22 14:13:51 +02:00
std :: pair < long , std :: vector < char >> common_remote_get_content ( const std :: string & url , const common_remote_params & params ) {
curl_ptr curl ( curl_easy_init (), & curl_easy_cleanup );
curl_slist_ptr http_headers ;
std :: vector < char > res_buffer ;
curl_easy_setopt ( curl . get (), CURLOPT_URL , url . c_str ());
curl_easy_setopt ( curl . get (), CURLOPT_NOPROGRESS , 1L );
curl_easy_setopt ( curl . get (), CURLOPT_FOLLOWLOCATION , 1L );
curl_easy_setopt ( curl . get (), CURLOPT_VERBOSE , 1L );
typedef size_t ( * CURLOPT_WRITEFUNCTION_PTR )( void * ptr , size_t size , size_t nmemb , void * data );
auto write_callback = []( void * ptr , size_t size , size_t nmemb , void * data ) -> size_t {
auto data_vec = static_cast < std :: vector < char > *> ( data );
data_vec -> insert ( data_vec -> end (), ( char * ) ptr , ( char * ) ptr + size * nmemb );
return size * nmemb ;
};
curl_easy_setopt ( curl . get (), CURLOPT_WRITEFUNCTION , static_cast < CURLOPT_WRITEFUNCTION_PTR > ( write_callback ));
curl_easy_setopt ( curl . get (), CURLOPT_WRITEDATA , & res_buffer );
#if defined(_WIN32)
curl_easy_setopt ( curl . get (), CURLOPT_SSL_OPTIONS , CURLSSLOPT_NATIVE_CA );
#endif
if ( params . timeout > 0 ) {
curl_easy_setopt ( curl . get (), CURLOPT_TIMEOUT , params . timeout );
}
if ( params . max_size > 0 ) {
curl_easy_setopt ( curl . get (), CURLOPT_MAXFILESIZE , params . max_size );
}
http_headers . ptr = curl_slist_append ( http_headers . ptr , "User-Agent: llama-cpp" );
for ( const auto & header : params . headers ) {
http_headers . ptr = curl_slist_append ( http_headers . ptr , header . c_str ());
}
curl_easy_setopt ( curl . get (), CURLOPT_HTTPHEADER , http_headers . ptr );
CURLcode res = curl_easy_perform ( curl . get ());
if ( res != CURLE_OK ) {
std :: string error_msg = curl_easy_strerror ( res );
throw std :: runtime_error ( "error: cannot make GET request: " + error_msg );
}
long res_code ;
curl_easy_getinfo ( curl . get (), CURLINFO_RESPONSE_CODE , & res_code );
return { res_code , std :: move ( res_buffer ) };
}
#else
2025-09-30 19:52:41 +02:00
static void print_progress ( size_t current , size_t total ) {
if ( ! is_output_a_tty ()) {
return ;
}
2025-09-26 13:12:19 +02:00
if ( ! total ) {
return ;
}
size_t width = 50 ;
size_t pct = ( 100 * current ) / total ;
size_t pos = ( width * current ) / total ;
std :: cout << "["
<< std :: string ( pos , '=' )
<< ( pos < width ? ">" : "" )
<< std :: string ( width - pos , ' ' )
<< "] " << std :: setw ( 3 ) << pct << "% ("
<< current / ( 1024 * 1024 ) << " MB / "
<< total / ( 1024 * 1024 ) << " MB) \r " ;
std :: cout . flush ();
}
static bool common_pull_file ( httplib :: Client & cli ,
const std :: string & resolve_path ,
const std :: string & path_tmp ,
bool supports_ranges ,
size_t existing_size ,
size_t & total_size ) {
std :: ofstream ofs ( path_tmp , std :: ios :: binary | std :: ios :: app );
if ( ! ofs . is_open ()) {
LOG_ERR ( "%s: error opening local file for writing: %s \n " , __func__ , path_tmp . c_str ());
return false ;
}
httplib :: Headers headers ;
if ( supports_ranges && existing_size > 0 ) {
headers . emplace ( "Range" , "bytes=" + std :: to_string ( existing_size ) + "-" );
}
std :: atomic < size_t > downloaded { existing_size };
auto res = cli . Get ( resolve_path , headers ,
[ & ]( const httplib :: Response & response ) {
if ( existing_size > 0 && response . status != 206 ) {
LOG_WRN ( "%s: server did not respond with 206 Partial Content for a resume request. Status: %d \n " , __func__ , response . status );
return false ;
}
if ( existing_size == 0 && response . status != 200 ) {
LOG_WRN ( "%s: download received non-successful status code: %d \n " , __func__ , response . status );
return false ;
}
if ( total_size == 0 && response . has_header ( "Content-Length" )) {
try {
size_t content_length = std :: stoull ( response . get_header_value ( "Content-Length" ));
total_size = existing_size + content_length ;
} catch ( const std :: exception & e ) {
LOG_WRN ( "%s: invalid Content-Length header: %s \n " , __func__ , e . what ());
}
}
return true ;
},
[ & ]( const char * data , size_t len ) {
ofs . write ( data , len );
if ( ! ofs ) {
LOG_ERR ( "%s: error writing to file: %s \n " , __func__ , path_tmp . c_str ());
return false ;
}
downloaded += len ;
print_progress ( downloaded , total_size );
return true ;
},
nullptr
);
std :: cout << " \n " ;
if ( ! res ) {
LOG_ERR ( "%s: error during download. Status: %d \n " , __func__ , res ? res -> status : - 1 );
return false ;
}
return true ;
}
// download one single file from remote URL to local path
static bool common_download_file_single_online ( const std :: string & url ,
const std :: string & path ,
const std :: string & bearer_token ) {
static const int max_attempts = 3 ;
static const int retry_delay_seconds = 2 ;
2025-10-01 19:22:18 +02:00
auto [ cli , parts ] = common_http_client ( url );
2025-09-26 13:12:19 +02:00
httplib :: Headers default_headers = {{ "User-Agent" , "llama-cpp" }};
if ( ! bearer_token . empty ()) {
default_headers . insert ({ "Authorization" , "Bearer " + bearer_token });
}
cli . set_default_headers ( default_headers );
const bool file_exists = std :: filesystem :: exists ( path );
2025-09-30 09:36:33 +02:00
std :: string last_etag ;
2025-09-26 13:12:19 +02:00
if ( file_exists ) {
2025-09-30 09:36:33 +02:00
last_etag = read_etag ( path );
2025-09-26 13:12:19 +02:00
} else {
LOG_INF ( "%s: no previous model file found %s \n " , __func__ , path . c_str ());
}
for ( int i = 0 ; i < max_attempts ; ++ i ) {
auto head = cli . Head ( parts . path );
bool head_ok = head && head -> status >= 200 && head -> status < 300 ;
if ( ! head_ok ) {
LOG_WRN ( "%s: HEAD invalid http status code received: %d \n " , __func__ , head ? head -> status : - 1 );
if ( file_exists ) {
LOG_INF ( "%s: Using cached file (HEAD failed): %s \n " , __func__ , path . c_str ());
return true ;
}
}
2025-09-30 09:36:33 +02:00
std :: string etag ;
if ( head_ok && head -> has_header ( "ETag" )) {
etag = head -> get_header_value ( "ETag" );
2025-09-26 13:12:19 +02:00
}
size_t total_size = 0 ;
if ( head_ok && head -> has_header ( "Content-Length" )) {
try {
total_size = std :: stoull ( head -> get_header_value ( "Content-Length" ));
} catch ( const std :: exception & e ) {
LOG_WRN ( "%s: Invalid Content-Length in HEAD response: %s \n " , __func__ , e . what ());
}
}
bool supports_ranges = false ;
if ( head_ok && head -> has_header ( "Accept-Ranges" )) {
supports_ranges = head -> get_header_value ( "Accept-Ranges" ) != "none" ;
}
bool should_download_from_scratch = false ;
2025-09-30 09:36:33 +02:00
if ( ! last_etag . empty () && ! etag . empty () && last_etag != etag ) {
LOG_WRN ( "%s: ETag header is different (%s != %s): triggering a new download \n " , __func__ ,
last_etag . c_str (), etag . c_str ());
should_download_from_scratch = true ;
2025-09-26 13:12:19 +02:00
}
if ( file_exists ) {
if ( ! should_download_from_scratch ) {
LOG_INF ( "%s: using cached file: %s \n " , __func__ , path . c_str ());
return true ;
}
LOG_WRN ( "%s: deleting previous downloaded file: %s \n " , __func__ , path . c_str ());
if ( remove ( path . c_str ()) != 0 ) {
LOG_ERR ( "%s: unable to delete file: %s \n " , __func__ , path . c_str ());
return false ;
}
}
const std :: string path_temporary = path + ".downloadInProgress" ;
size_t existing_size = 0 ;
if ( std :: filesystem :: exists ( path_temporary )) {
if ( supports_ranges && ! should_download_from_scratch ) {
existing_size = std :: filesystem :: file_size ( path_temporary );
} else if ( remove ( path_temporary . c_str ()) != 0 ) {
LOG_ERR ( "%s: unable to delete file: %s \n " , __func__ , path_temporary . c_str ());
return false ;
}
}
// start the download
2025-09-30 09:36:33 +02:00
LOG_INF ( "%s: trying to download model from %s to %s (etag:%s)... \n " ,
2025-10-01 19:22:18 +02:00
__func__ , common_http_show_masked_url ( parts ). c_str (), path_temporary . c_str (), etag . c_str ());
2025-09-26 13:12:19 +02:00
const bool was_pull_successful = common_pull_file ( cli , parts . path , path_temporary , supports_ranges , existing_size , total_size );
if ( ! was_pull_successful ) {
if ( i + 1 < max_attempts ) {
const int exponential_backoff_delay = std :: pow ( retry_delay_seconds , i ) * 1000 ;
LOG_WRN ( "%s: retrying after %d milliseconds... \n " , __func__ , exponential_backoff_delay );
std :: this_thread :: sleep_for ( std :: chrono :: milliseconds ( exponential_backoff_delay ));
} else {
LOG_ERR ( "%s: download failed after %d attempts \n " , __func__ , max_attempts );
}
continue ;
}
if ( std :: rename ( path_temporary . c_str (), path . c_str ()) != 0 ) {
LOG_ERR ( "%s: unable to rename file: %s to %s \n " , __func__ , path_temporary . c_str (), path . c_str ());
return false ;
}
2025-09-30 09:36:33 +02:00
if ( ! etag . empty ()) {
write_etag ( path , etag );
}
2025-09-26 13:12:19 +02:00
break ;
}
return true ;
}
std :: pair < long , std :: vector < char >> common_remote_get_content ( const std :: string & url ,
const common_remote_params & params ) {
2025-10-01 19:22:18 +02:00
auto [ cli , parts ] = common_http_client ( url );
2025-09-26 13:12:19 +02:00
httplib :: Headers headers = {{ "User-Agent" , "llama-cpp" }};
for ( const auto & header : params . headers ) {
size_t pos = header . find ( ':' );
if ( pos != std :: string :: npos ) {
headers . emplace ( header . substr ( 0 , pos ), header . substr ( pos + 1 ));
} else {
headers . emplace ( header , "" );
}
}
if ( params . timeout > 0 ) {
cli . set_read_timeout ( params . timeout , 0 );
cli . set_write_timeout ( params . timeout , 0 );
}
std :: vector < char > buf ;
auto res = cli . Get ( parts . path , headers ,
[ & ]( const char * data , size_t len ) {
buf . insert ( buf . end (), data , data + len );
return params . max_size == 0 ||
buf . size () <= static_cast < size_t > ( params . max_size );
},
nullptr
);
if ( ! res ) {
throw std :: runtime_error ( "error: cannot make GET request" );
}
return { res -> status , std :: move ( buf ) };
2025-09-22 14:13:51 +02:00
}
#endif // LLAMA_USE_CURL
static bool common_download_file_single ( const std :: string & url ,
const std :: string & path ,
const std :: string & bearer_token ,
bool offline ) {
if ( ! offline ) {
return common_download_file_single_online ( url , path , bearer_token );
}
if ( ! std :: filesystem :: exists ( path )) {
LOG_ERR ( "%s: required file is not available in cache (offline mode): %s \n " , __func__ , path . c_str ());
return false ;
}
LOG_INF ( "%s: using cached file (offline mode): %s \n " , __func__ , path . c_str ());
return true ;
}
2025-04-01 23:44:05 +02:00
// download multiple files from remote URLs to local paths
// the input is a vector of pairs <url, path>
2025-05-26 14:34:27 -07:00
static bool common_download_file_multiple ( const std :: vector < std :: pair < std :: string , std :: string >> & urls , const std :: string & bearer_token , bool offline ) {
2025-04-01 23:44:05 +02:00
// Prepare download in parallel
std :: vector < std :: future < bool >> futures_download ;
for ( auto const & item : urls ) {
2025-05-26 14:34:27 -07:00
futures_download . push_back ( std :: async ( std :: launch :: async , [ bearer_token , offline ]( const std :: pair < std :: string , std :: string > & it ) -> bool {
return common_download_file_single ( it . first , it . second , bearer_token , offline );
2025-04-01 23:44:05 +02:00
}, item ));
}
// Wait for all downloads to complete
for ( auto & f : futures_download ) {
if ( ! f . get ()) {
return false ;
}
}
return true ;
}
static bool common_download_model (
const common_params_model & model ,
2025-05-26 14:34:27 -07:00
const std :: string & bearer_token ,
bool offline ) {
2025-04-01 23:44:05 +02:00
// Basic validation of the model.url
if ( model . url . empty ()) {
LOG_ERR ( "%s: invalid model url \n " , __func__ );
return false ;
}
2025-05-26 14:34:27 -07:00
if ( ! common_download_file_single ( model . url , model . path , bearer_token , offline )) {
2025-04-01 23:44:05 +02:00
return false ;
}
// check for additional GGUFs split to download
int n_split = 0 ;
{
struct gguf_init_params gguf_params = {
/*.no_alloc = */ true ,
/*.ctx = */ NULL ,
};
auto * ctx_gguf = gguf_init_from_file ( model . path . c_str (), gguf_params );
if ( ! ctx_gguf ) {
LOG_ERR ( " \n %s: failed to load input GGUF from %s \n " , __func__ , model . path . c_str ());
return false ;
}
auto key_n_split = gguf_find_key ( ctx_gguf , LLM_KV_SPLIT_COUNT );
if ( key_n_split >= 0 ) {
n_split = gguf_get_val_u16 ( ctx_gguf , key_n_split );
}
gguf_free ( ctx_gguf );
}
if ( n_split > 1 ) {
char split_prefix [ PATH_MAX ] = { 0 };
2025-09-22 14:13:51 +02:00
char split_url_prefix [ LLAMA_MAX_URL_LENGTH ] = { 0 };
2025-04-01 23:44:05 +02:00
// Verify the first split file format
// and extract split URL and PATH prefixes
{
if ( ! llama_split_prefix ( split_prefix , sizeof ( split_prefix ), model . path . c_str (), 0 , n_split )) {
LOG_ERR ( " \n %s: unexpected model file name: %s n_split=%d \n " , __func__ , model . path . c_str (), n_split );
return false ;
}
if ( ! llama_split_prefix ( split_url_prefix , sizeof ( split_url_prefix ), model . url . c_str (), 0 , n_split )) {
LOG_ERR ( " \n %s: unexpected model url: %s n_split=%d \n " , __func__ , model . url . c_str (), n_split );
return false ;
}
}
std :: vector < std :: pair < std :: string , std :: string >> urls ;
for ( int idx = 1 ; idx < n_split ; idx ++ ) {
char split_path [ PATH_MAX ] = { 0 };
llama_split_path ( split_path , sizeof ( split_path ), split_prefix , idx , n_split );
2025-09-22 14:13:51 +02:00
char split_url [ LLAMA_MAX_URL_LENGTH ] = { 0 };
2025-04-01 23:44:05 +02:00
llama_split_path ( split_url , sizeof ( split_url ), split_url_prefix , idx , n_split );
if ( std :: string ( split_path ) == model . path ) {
continue ; // skip the already downloaded file
}
urls . push_back ({ split_url , split_path });
}
// Download in parallel
2025-05-26 14:34:27 -07:00
common_download_file_multiple ( urls , bearer_token , offline );
2025-04-01 23:44:05 +02:00
}
return true ;
}
/**
* Allow getting the HF file from the HF repo with tag (like ollama), for example:
* - bartowski/Llama-3.2-3B-Instruct-GGUF:q4
* - bartowski/Llama-3.2-3B-Instruct-GGUF:Q4_K_M
* - bartowski/Llama-3.2-3B-Instruct-GGUF:q5_k_s
* Tag is optional, default to "latest" (meaning it checks for Q4_K_M first, then Q4, then if not found, return the first GGUF file in repo)
*
* Return pair of <repo, file> (with "repo" already having tag removed)
*
* Note: we use the Ollama-compatible HF API, but not using the blobId. Instead, we use the special "ggufFile" field which returns the value for "hf_file". This is done to be backward-compatible with existing cache files.
*/
2025-05-26 14:34:27 -07:00
static struct common_hf_file_res common_get_hf_file ( const std :: string & hf_repo_with_tag , const std :: string & bearer_token , bool offline ) {
2025-04-01 23:44:05 +02:00
auto parts = string_split < std :: string > ( hf_repo_with_tag , ':' );
std :: string tag = parts . size () > 1 ? parts . back () : "latest" ;
std :: string hf_repo = parts [ 0 ];
if ( string_split < std :: string > ( hf_repo , '/' ). size () != 2 ) {
throw std :: invalid_argument ( "error: invalid HF repo format, expected <user>/<model>[:quant] \n " );
}
2025-04-26 22:58:12 +02:00
std :: string url = get_model_endpoint () + "v2/" + hf_repo + "/manifests/" + tag ;
2025-04-11 20:01:56 +08:00
2025-04-26 22:58:12 +02:00
// headers
std :: vector < std :: string > headers ;
headers . push_back ( "Accept: application/json" );
2025-04-01 23:44:05 +02:00
if ( ! bearer_token . empty ()) {
2025-04-26 22:58:12 +02:00
headers . push_back ( "Authorization: Bearer " + bearer_token );
2025-04-01 23:44:05 +02:00
}
// Important: the User-Agent must be "llama-cpp" to get the "ggufFile" field in the response
2025-04-26 22:58:12 +02:00
// User-Agent header is already set in common_remote_get_content, no need to set it here
2025-04-01 23:44:05 +02:00
2025-04-30 10:46:32 +02:00
// we use "=" to avoid clashing with other component, while still being allowed on windows
std :: string cached_response_fname = "manifest=" + hf_repo + "=" + tag + ".json" ;
string_replace_all ( cached_response_fname , "/" , "_" );
std :: string cached_response_path = fs_get_cache_file ( cached_response_fname );
2025-04-26 22:58:12 +02:00
// make the request
common_remote_params params ;
params . headers = headers ;
2025-04-30 10:46:32 +02:00
long res_code = 0 ;
std :: string res_str ;
bool use_cache = false ;
2025-05-26 14:34:27 -07:00
if ( ! offline ) {
2025-04-30 10:46:32 +02:00
try {
2025-05-26 14:34:27 -07:00
auto res = common_remote_get_content ( url , params );
res_code = res . first ;
res_str = std :: string ( res . second . data (), res . second . size ());
} catch ( const std :: exception & e ) {
LOG_WRN ( "error: failed to get manifest at %s: %s \n " , url . c_str (), e . what ());
}
}
if ( res_code == 0 ) {
if ( std :: filesystem :: exists ( cached_response_path )) {
LOG_WRN ( "trying to read manifest from cache: %s \n " , cached_response_path . c_str ());
2025-04-30 10:46:32 +02:00
res_str = read_file ( cached_response_path );
res_code = 200 ;
use_cache = true ;
2025-05-26 14:34:27 -07:00
} else {
throw std :: runtime_error (
offline ? "error: failed to get manifest (offline mode)"
: "error: failed to get manifest (check your internet connection)" );
2025-04-30 10:46:32 +02:00
}
}
2025-04-26 22:58:12 +02:00
std :: string ggufFile ;
std :: string mmprojFile ;
2025-04-01 23:44:05 +02:00
2025-04-30 10:46:32 +02:00
if ( res_code == 200 || res_code == 304 ) {
2025-09-22 14:13:51 +02:00
try {
auto j = json :: parse ( res_str );
if ( j . contains ( "ggufFile" ) && j [ "ggufFile" ]. contains ( "rfilename" )) {
ggufFile = j [ "ggufFile" ][ "rfilename" ]. get < std :: string > ();
2025-04-01 23:44:05 +02:00
}
2025-09-22 14:13:51 +02:00
if ( j . contains ( "mmprojFile" ) && j [ "mmprojFile" ]. contains ( "rfilename" )) {
mmprojFile = j [ "mmprojFile" ][ "rfilename" ]. get < std :: string > ();
2025-04-01 23:44:05 +02:00
}
2025-09-22 14:13:51 +02:00
} catch ( const std :: exception & e ) {
throw std :: runtime_error ( std :: string ( "error parsing manifest JSON: " ) + e . what ());
2025-04-01 23:44:05 +02:00
}
2025-04-30 10:46:32 +02:00
if ( ! use_cache ) {
// if not using cached response, update the cache file
write_file ( cached_response_path , res_str );
}
2025-04-01 23:44:05 +02:00
} else if ( res_code == 401 ) {
throw std :: runtime_error ( "error: model is private or does not exist; if you are accessing a gated model, please provide a valid HF token" );
} else {
throw std :: runtime_error ( string_format ( "error from HF API, response code: %ld, data: %s" , res_code , res_str . c_str ()));
}
// check response
if ( ggufFile . empty ()) {
throw std :: runtime_error ( "error: model does not have ggufFile" );
}
return { hf_repo , ggufFile , mmprojFile };
}
2025-09-12 16:31:50 +01:00
//
// Docker registry functions
//
static std :: string common_docker_get_token ( const std :: string & repo ) {
std :: string url = "https://auth.docker.io/token?service=registry.docker.io&scope=repository:" + repo + ":pull" ;
common_remote_params params ;
auto res = common_remote_get_content ( url , params );
if ( res . first != 200 ) {
throw std :: runtime_error ( "Failed to get Docker registry token, HTTP code: " + std :: to_string ( res . first ));
}
std :: string response_str ( res . second . begin (), res . second . end ());
nlohmann :: ordered_json response = nlohmann :: ordered_json :: parse ( response_str );
if ( ! response . contains ( "token" )) {
throw std :: runtime_error ( "Docker registry token response missing 'token' field" );
}
return response [ "token" ]. get < std :: string > ();
}
static std :: string common_docker_resolve_model ( const std :: string & docker ) {
2025-09-18 16:22:50 +01:00
// Parse ai/smollm2:135M-Q4_0
2025-09-12 16:31:50 +01:00
size_t colon_pos = docker . find ( ':' );
std :: string repo , tag ;
if ( colon_pos != std :: string :: npos ) {
repo = docker . substr ( 0 , colon_pos );
tag = docker . substr ( colon_pos + 1 );
} else {
repo = docker ;
tag = "latest" ;
}
// ai/ is the default
size_t slash_pos = docker . find ( '/' );
if ( slash_pos == std :: string :: npos ) {
repo . insert ( 0 , "ai/" );
}
LOG_INF ( "%s: Downloading Docker Model: %s:%s \n " , __func__ , repo . c_str (), tag . c_str ());
try {
// --- helper: digest validation ---
auto validate_oci_digest = []( const std :: string & digest ) -> std :: string {
// Expected: algo:hex ; start with sha256 (64 hex chars)
// You can extend this map if supporting other algorithms in future.
static const std :: regex re ( "^sha256:([a-fA-F0-9]{64})$" );
std :: smatch m ;
if ( ! std :: regex_match ( digest , m , re )) {
throw std :: runtime_error ( "Invalid OCI digest format received in manifest: " + digest );
}
// normalize hex to lowercase
std :: string normalized = digest ;
std :: transform ( normalized . begin () + 7 , normalized . end (), normalized . begin () + 7 , []( unsigned char c ){
return std :: tolower ( c );
});
return normalized ;
};
std :: string token = common_docker_get_token ( repo ); // Get authentication token
// Get manifest
const std :: string url_prefix = "https://registry-1.docker.io/v2/" + repo ;
std :: string manifest_url = url_prefix + "/manifests/" + tag ;
common_remote_params manifest_params ;
manifest_params . headers . push_back ( "Authorization: Bearer " + token );
manifest_params . headers . push_back (
"Accept: application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json" );
auto manifest_res = common_remote_get_content ( manifest_url , manifest_params );
if ( manifest_res . first != 200 ) {
throw std :: runtime_error ( "Failed to get Docker manifest, HTTP code: " + std :: to_string ( manifest_res . first ));
}
std :: string manifest_str ( manifest_res . second . begin (), manifest_res . second . end ());
nlohmann :: ordered_json manifest = nlohmann :: ordered_json :: parse ( manifest_str );
std :: string gguf_digest ; // Find the GGUF layer
if ( manifest . contains ( "layers" )) {
for ( const auto & layer : manifest [ "layers" ]) {
if ( layer . contains ( "mediaType" )) {
std :: string media_type = layer [ "mediaType" ]. get < std :: string > ();
if ( media_type == "application/vnd.docker.ai.gguf.v3" ||
media_type . find ( "gguf" ) != std :: string :: npos ) {
gguf_digest = layer [ "digest" ]. get < std :: string > ();
break ;
}
}
}
}
if ( gguf_digest . empty ()) {
throw std :: runtime_error ( "No GGUF layer found in Docker manifest" );
}
// Validate & normalize digest
gguf_digest = validate_oci_digest ( gguf_digest );
LOG_DBG ( "%s: Using validated digest: %s \n " , __func__ , gguf_digest . c_str ());
// Prepare local filename
std :: string model_filename = repo ;
std :: replace ( model_filename . begin (), model_filename . end (), '/' , '_' );
model_filename += "_" + tag + ".gguf" ;
std :: string local_path = fs_get_cache_file ( model_filename );
const std :: string blob_url = url_prefix + "/blobs/" + gguf_digest ;
if ( ! common_download_file_single ( blob_url , local_path , token , false )) {
throw std :: runtime_error ( "Failed to download Docker Model" );
}
LOG_INF ( "%s: Downloaded Docker Model to: %s \n " , __func__ , local_path . c_str ());
return local_path ;
} catch ( const std :: exception & e ) {
LOG_ERR ( "%s: Docker Model download failed: %s \n " , __func__ , e . what ());
throw ;
}
}
2024-09-09 23:36:09 +02:00
//
// utils
//
2025-08-13 12:44:40 +02:00
// Helper function to parse tensor buffer override strings
static void parse_tensor_buffer_overrides ( const std :: string & value , std :: vector < llama_model_tensor_buft_override > & overrides ) {
std :: map < std :: string , ggml_backend_buffer_type_t > buft_list ;
for ( size_t i = 0 ; i < ggml_backend_dev_count (); ++ i ) {
auto * dev = ggml_backend_dev_get ( i );
auto * buft = ggml_backend_dev_buffer_type ( dev );
if ( buft ) {
buft_list [ ggml_backend_buft_name ( buft )] = buft ;
}
}
for ( const auto & override : string_split < std :: string > ( value , ',' )) {
std :: string :: size_type pos = override . find ( '=' );
if ( pos == std :: string :: npos ) {
throw std :: invalid_argument ( "invalid value" );
}
std :: string tensor_name = override . substr ( 0 , pos );
std :: string buffer_type = override . substr ( pos + 1 );
if ( buft_list . find ( buffer_type ) == buft_list . end ()) {
printf ( "Available buffer types: \n " );
for ( const auto & it : buft_list ) {
printf ( " %s \n " , ggml_backend_buft_name ( it . second ));
}
throw std :: invalid_argument ( "unknown buffer type" );
}
// keep strings alive and avoid leaking memory by storing them in a static vector
static std :: list < std :: string > buft_overrides ;
buft_overrides . push_back ( tensor_name );
overrides . push_back ({ buft_overrides . back (). c_str (), buft_list . at ( buffer_type )});
}
}
2025-04-24 12:14:13 +02:00
struct handle_model_result {
bool found_mmproj = false ;
common_params_model mmproj ;
};
static handle_model_result common_params_handle_model (
2025-04-01 23:44:05 +02:00
struct common_params_model & model ,
const std :: string & bearer_token ,
2025-05-26 14:34:27 -07:00
const std :: string & model_path_default ,
bool offline ) {
2025-04-24 12:14:13 +02:00
handle_model_result result ;
2025-04-01 23:44:05 +02:00
// handle pre-fill default model path and url based on hf_repo and hf_file
{
2025-09-12 16:31:50 +01:00
if ( ! model . docker_repo . empty ()) { // Handle Docker URLs by resolving them to local paths
model . path = common_docker_resolve_model ( model . docker_repo );
} else if ( ! model . hf_repo . empty ()) {
2025-04-01 23:44:05 +02:00
// short-hand to avoid specifying --hf-file -> default it to --model
if ( model . hf_file . empty ()) {
if ( model . path . empty ()) {
2025-05-26 14:34:27 -07:00
auto auto_detected = common_get_hf_file ( model . hf_repo , bearer_token , offline );
2025-04-01 23:44:05 +02:00
if ( auto_detected . repo . empty () || auto_detected . ggufFile . empty ()) {
exit ( 1 ); // built without CURL, error message already printed
}
model . hf_repo = auto_detected . repo ;
2025-04-24 12:14:13 +02:00
model . hf_file = auto_detected . ggufFile ;
if ( ! auto_detected . mmprojFile . empty ()) {
result . found_mmproj = true ;
result . mmproj . hf_repo = model . hf_repo ;
result . mmproj . hf_file = auto_detected . mmprojFile ;
}
2025-04-01 23:44:05 +02:00
} else {
model . hf_file = model . path ;
2025-01-13 13:56:23 +01:00
}
2024-09-09 23:36:09 +02:00
}
2025-04-01 23:44:05 +02:00
2025-04-11 20:01:56 +08:00
std :: string model_endpoint = get_model_endpoint ();
model . url = model_endpoint + model . hf_repo + "/resolve/main/" + model . hf_file ;
2025-04-01 23:44:05 +02:00
// make sure model path is present (for caching purposes)
if ( model . path . empty ()) {
// this is to avoid different repo having same file name, or same file name in different subdirs
std :: string filename = model . hf_repo + "_" + model . hf_file ;
// to make sure we don't have any slashes in the filename
string_replace_all ( filename , "/" , "_" );
model . path = fs_get_cache_file ( filename );
}
} else if ( ! model . url . empty ()) {
if ( model . path . empty ()) {
auto f = string_split < std :: string > ( model . url , '#' ). front ();
f = string_split < std :: string > ( f , '?' ). front ();
model . path = fs_get_cache_file ( string_split < std :: string > ( f , '/' ). back ());
}
} else if ( model . path . empty ()) {
model . path = model_path_default ;
2025-01-13 13:56:23 +01:00
}
2025-04-01 23:44:05 +02:00
}
// then, download it if needed
if ( ! model . url . empty ()) {
2025-05-26 14:34:27 -07:00
bool ok = common_download_model ( model , bearer_token , offline );
2025-04-01 23:44:05 +02:00
if ( ! ok ) {
LOG_ERR ( "error: failed to download model from %s \n " , model . url . c_str ());
exit ( 1 );
2024-09-09 23:36:09 +02:00
}
}
2025-04-24 12:14:13 +02:00
return result ;
2024-09-09 23:36:09 +02:00
}
2024-12-12 22:53:05 +01:00
const std :: vector < ggml_type > kv_cache_types = {
GGML_TYPE_F32 ,
GGML_TYPE_F16 ,
GGML_TYPE_BF16 ,
GGML_TYPE_Q8_0 ,
GGML_TYPE_Q4_0 ,
GGML_TYPE_Q4_1 ,
GGML_TYPE_IQ4_NL ,
GGML_TYPE_Q5_0 ,
GGML_TYPE_Q5_1 ,
};
static ggml_type kv_cache_type_from_str ( const std :: string & s ) {
for ( const auto & type : kv_cache_types ) {
if ( ggml_type_name ( type ) == s ) {
return type ;
}
}
throw std :: runtime_error ( "Unsupported cache type: " + s );
}
static std :: string get_all_kv_cache_types () {
std :: ostringstream msg ;
for ( const auto & type : kv_cache_types ) {
msg << ggml_type_name ( type ) << ( & type == & kv_cache_types . back () ? "" : ", " );
}
return msg . str ();
}
2024-09-09 23:36:09 +02:00
//
// CLI argument parsing functions
//
2024-10-10 22:57:42 +02:00
static bool common_params_parse_ex ( int argc , char ** argv , common_params_context & ctx_arg ) {
common_params & params = ctx_arg . params ;
2024-09-09 23:36:09 +02:00
2024-10-10 22:57:42 +02:00
std :: unordered_map < std :: string , common_arg *> arg_to_options ;
2024-09-09 23:36:09 +02:00
for ( auto & opt : ctx_arg . options ) {
for ( const auto & arg : opt . args ) {
arg_to_options [ arg ] = & opt ;
}
}
// handle environment variables
for ( auto & opt : ctx_arg . options ) {
std :: string value ;
if ( opt . get_value_from_env ( value )) {
try {
if ( opt . handler_void && ( value == "1" || value == "true" )) {
opt . handler_void ( params );
}
if ( opt . handler_int ) {
opt . handler_int ( params , std :: stoi ( value ));
}
if ( opt . handler_string ) {
opt . handler_string ( params , value );
continue ;
}
} catch ( std :: exception & e ) {
2024-10-12 08:21:51 +03:00
throw std :: invalid_argument ( string_format (
2024-09-09 23:36:09 +02:00
"error while handling environment variable \" %s \" : %s \n\n " , opt . env , e . what ()));
}
}
}
// handle command line arguments
auto check_arg = [ & ]( int i ) {
if ( i + 1 >= argc ) {
throw std :: invalid_argument ( "expected value for argument" );
}
};
for ( int i = 1 ; i < argc ; i ++ ) {
const std :: string arg_prefix = "--" ;
std :: string arg = argv [ i ];
if ( arg . compare ( 0 , arg_prefix . size (), arg_prefix ) == 0 ) {
std :: replace ( arg . begin (), arg . end (), '_' , '-' );
}
if ( arg_to_options . find ( arg ) == arg_to_options . end ()) {
2024-10-12 08:21:51 +03:00
throw std :: invalid_argument ( string_format ( "error: invalid argument: %s" , arg . c_str ()));
2024-09-09 23:36:09 +02:00
}
auto opt = * arg_to_options [ arg ];
if ( opt . has_value_from_env ()) {
fprintf ( stderr , "warn: %s environment variable is set, but will be overwritten by command line argument %s \n " , opt . env , arg . c_str ());
}
try {
if ( opt . handler_void ) {
opt . handler_void ( params );
continue ;
}
// arg with single value
check_arg ( i );
std :: string val = argv [ ++ i ];
if ( opt . handler_int ) {
opt . handler_int ( params , std :: stoi ( val ));
continue ;
}
if ( opt . handler_string ) {
opt . handler_string ( params , val );
continue ;
}
// arg with 2 values
check_arg ( i );
std :: string val2 = argv [ ++ i ];
if ( opt . handler_str_str ) {
opt . handler_str_str ( params , val , val2 );
continue ;
}
} catch ( std :: exception & e ) {
2024-10-12 08:21:51 +03:00
throw std :: invalid_argument ( string_format (
2024-09-09 23:36:09 +02:00
"error while handling argument \" %s \" : %s \n\n "
"usage: \n %s \n\n to show complete usage, run with -h" ,
arg . c_str (), e . what (), arg_to_options [ arg ] -> to_string (). c_str ()));
}
}
2024-11-25 09:58:41 +02:00
postprocess_cpu_params ( params . cpuparams , nullptr );
2024-09-09 23:36:09 +02:00
postprocess_cpu_params ( params . cpuparams_batch , & params . cpuparams );
2024-11-25 09:58:41 +02:00
postprocess_cpu_params ( params . speculative . cpuparams , & params . cpuparams );
postprocess_cpu_params ( params . speculative . cpuparams_batch , & params . cpuparams_batch );
2024-09-09 23:36:09 +02:00
if ( params . prompt_cache_all && ( params . interactive || params . interactive_first )) {
throw std :: invalid_argument ( "error: --prompt-cache-all not supported in interactive mode yet \n " );
}
2025-04-24 12:14:13 +02:00
// handle model and download
{
2025-05-26 14:34:27 -07:00
auto res = common_params_handle_model ( params . model , params . hf_token , DEFAULT_MODEL_PATH , params . offline );
2025-04-24 12:14:13 +02:00
if ( params . no_mmproj ) {
params . mmproj = {};
} else if ( res . found_mmproj && params . mmproj . path . empty () && params . mmproj . url . empty ()) {
// optionally, handle mmproj model when -hf is specified
params . mmproj = res . mmproj ;
}
// only download mmproj if the current example is using it
for ( auto & ex : mmproj_examples ) {
if ( ctx_arg . ex == ex ) {
2025-05-26 14:34:27 -07:00
common_params_handle_model ( params . mmproj , params . hf_token , "" , params . offline );
2025-04-24 12:14:13 +02:00
break ;
}
}
2025-05-26 14:34:27 -07:00
common_params_handle_model ( params . speculative . model , params . hf_token , "" , params . offline );
common_params_handle_model ( params . vocoder . model , params . hf_token , "" , params . offline );
2025-04-01 23:44:05 +02:00
}
2024-09-09 23:36:09 +02:00
if ( params . escape ) {
string_process_escapes ( params . prompt );
string_process_escapes ( params . input_prefix );
string_process_escapes ( params . input_suffix );
for ( auto & antiprompt : params . antiprompt ) {
string_process_escapes ( antiprompt );
}
2024-11-25 09:58:41 +02:00
for ( auto & seq_breaker : params . sampling . dry_sequence_breakers ) {
2024-10-25 10:07:34 -06:00
string_process_escapes ( seq_breaker );
}
2025-07-31 05:25:23 -07:00
for ( auto & pair : params . speculative . replacements ) {
string_process_escapes ( pair . first );
string_process_escapes ( pair . second );
}
2024-09-09 23:36:09 +02:00
}
if ( ! params . kv_overrides . empty ()) {
params . kv_overrides . emplace_back ();
params . kv_overrides . back (). key [ 0 ] = 0 ;
}
2025-04-02 14:52:01 +02:00
if ( ! params . tensor_buft_overrides . empty ()) {
params . tensor_buft_overrides . push_back ({ nullptr , nullptr });
}
2025-08-13 12:44:40 +02:00
if ( ! params . speculative . tensor_buft_overrides . empty ()) {
params . speculative . tensor_buft_overrides . push_back ({ nullptr , nullptr });
}
2025-01-21 13:18:51 +00:00
if ( ! params . chat_template . empty () && ! common_chat_verify_template ( params . chat_template , params . use_jinja )) {
throw std :: runtime_error ( string_format (
"error: the supplied chat template is not supported: %s%s \n " ,
params . chat_template . c_str (),
params . use_jinja ? "" : " \n note: llama.cpp was started without --jinja, we only support commonly used templates"
));
}
2024-09-09 23:36:09 +02:00
return true ;
}
2024-10-10 22:57:42 +02:00
static void common_params_print_usage ( common_params_context & ctx_arg ) {
auto print_options = []( std :: vector < common_arg *> & options ) {
for ( common_arg * opt : options ) {
2024-09-09 23:36:09 +02:00
printf ( "%s" , opt -> to_string (). c_str ());
}
};
2024-10-10 22:57:42 +02:00
std :: vector < common_arg *> common_options ;
std :: vector < common_arg *> sparam_options ;
std :: vector < common_arg *> specific_options ;
2024-09-09 23:36:09 +02:00
for ( auto & opt : ctx_arg . options ) {
// in case multiple LLAMA_EXAMPLE_* are set, we prioritize the LLAMA_EXAMPLE_* matching current example
if ( opt . is_sparam ) {
sparam_options . push_back ( & opt );
} else if ( opt . in_example ( ctx_arg . ex )) {
specific_options . push_back ( & opt );
} else {
common_options . push_back ( & opt );
}
}
printf ( "----- common params ----- \n\n " );
print_options ( common_options );
printf ( " \n\n ----- sampling params ----- \n\n " );
print_options ( sparam_options );
// TODO: maybe convert enum llama_example to string
printf ( " \n\n ----- example-specific params ----- \n\n " );
print_options ( specific_options );
}
2025-02-13 14:46:59 +01:00
static void common_params_print_completion ( common_params_context & ctx_arg ) {
std :: vector < common_arg *> common_options ;
std :: vector < common_arg *> sparam_options ;
std :: vector < common_arg *> specific_options ;
for ( auto & opt : ctx_arg . options ) {
if ( opt . is_sparam ) {
sparam_options . push_back ( & opt );
} else if ( opt . in_example ( ctx_arg . ex )) {
specific_options . push_back ( & opt );
} else {
common_options . push_back ( & opt );
}
}
printf ( "_llama_completions() { \n " );
printf ( " local cur prev opts \n " );
printf ( " COMPREPLY=() \n " );
printf ( " cur= \" ${COMP_WORDS[COMP_CWORD]} \"\n " );
printf ( " prev= \" ${COMP_WORDS[COMP_CWORD-1]} \"\n\n " );
printf ( " opts= \" " );
auto print_options = []( const std :: vector < common_arg *> & options ) {
for ( const common_arg * opt : options ) {
for ( const char * arg : opt -> args ) {
printf ( "%s " , arg );
}
}
};
print_options ( common_options );
print_options ( sparam_options );
print_options ( specific_options );
printf ( " \"\n\n " );
printf ( " case \" $prev \" in \n " );
2025-08-27 10:28:53 +02:00
printf ( " --model|-m) \n " );
2025-02-13 14:46:59 +01:00
printf ( " COMPREPLY=( $(compgen -f -X '!*.gguf' -- \" $cur \" ) $(compgen -d -- \" $cur \" ) ) \n " );
printf ( " return 0 \n " );
printf ( " ;; \n " );
printf ( " --grammar-file) \n " );
printf ( " COMPREPLY=( $(compgen -f -X '!*.gbnf' -- \" $cur \" ) $(compgen -d -- \" $cur \" ) ) \n " );
printf ( " return 0 \n " );
2025-02-14 11:16:56 +01:00
printf ( " ;; \n " );
printf ( " --chat-template-file) \n " );
printf ( " COMPREPLY=( $(compgen -f -X '!*.jinja' -- \" $cur \" ) $(compgen -d -- \" $cur \" ) ) \n " );
printf ( " return 0 \n " );
2025-02-13 14:46:59 +01:00
printf ( " ;; \n " );
printf ( " *) \n " );
printf ( " COMPREPLY=( $(compgen -W \" ${opts} \" -- \" $cur \" ) ) \n " );
printf ( " return 0 \n " );
printf ( " ;; \n " );
printf ( " esac \n " );
printf ( "} \n\n " );
std :: set < std :: string > executables = {
"llama-batched" ,
"llama-batched-bench" ,
"llama-bench" ,
"llama-cli" ,
"llama-convert-llama2c-to-ggml" ,
"llama-cvector-generator" ,
"llama-embedding" ,
"llama-eval-callback" ,
"llama-export-lora" ,
"llama-gen-docs" ,
"llama-gguf" ,
"llama-gguf-hash" ,
"llama-gguf-split" ,
"llama-gritlm" ,
"llama-imatrix" ,
"llama-infill" ,
2025-04-22 10:37:00 +02:00
"llama-mtmd-cli" ,
2025-02-13 14:46:59 +01:00
"llama-llava-clip-quantize-cli" ,
"llama-lookahead" ,
"llama-lookup" ,
"llama-lookup-create" ,
"llama-lookup-merge" ,
"llama-lookup-stats" ,
"llama-parallel" ,
"llama-passkey" ,
"llama-perplexity" ,
"llama-q8dot" ,
"llama-quantize" ,
"llama-qwen2vl-cli" ,
"llama-retrieval" ,
"llama-run" ,
"llama-save-load-state" ,
"llama-server" ,
"llama-simple" ,
"llama-simple-chat" ,
"llama-speculative" ,
"llama-speculative-simple" ,
"llama-tokenize" ,
"llama-tts" ,
"llama-vdot"
};
for ( const auto & exe : executables ) {
printf ( "complete -F _llama_completions %s \n " , exe . c_str ());
}
}
2024-11-25 19:30:06 +01:00
static std :: vector < ggml_backend_dev_t > parse_device_list ( const std :: string & value ) {
std :: vector < ggml_backend_dev_t > devices ;
auto dev_names = string_split < std :: string > ( value , ',' );
if ( dev_names . empty ()) {
throw std :: invalid_argument ( "no devices specified" );
}
if ( dev_names . size () == 1 && dev_names [ 0 ] == "none" ) {
devices . push_back ( nullptr );
} else {
for ( const auto & device : dev_names ) {
auto * dev = ggml_backend_dev_by_name ( device . c_str ());
2025-09-13 07:49:49 -07:00
if ( ! dev || ggml_backend_dev_type ( dev ) == GGML_BACKEND_DEVICE_TYPE_CPU ) {
2024-11-25 19:30:06 +01:00
throw std :: invalid_argument ( string_format ( "invalid device: %s" , device . c_str ()));
}
devices . push_back ( dev );
}
devices . push_back ( nullptr );
}
return devices ;
}
2025-09-13 07:49:49 -07:00
static void add_rpc_devices ( const std :: string & servers ) {
2025-01-17 10:57:09 +02:00
auto rpc_servers = string_split < std :: string > ( servers , ',' );
if ( rpc_servers . empty ()) {
throw std :: invalid_argument ( "no RPC servers specified" );
}
ggml_backend_reg_t rpc_reg = ggml_backend_reg_by_name ( "RPC" );
if ( ! rpc_reg ) {
throw std :: invalid_argument ( "failed to find RPC backend" );
}
2025-10-04 12:49:16 +03:00
typedef ggml_backend_reg_t ( * ggml_backend_rpc_add_server_t )( const char * endpoint );
ggml_backend_rpc_add_server_t ggml_backend_rpc_add_server_fn = ( ggml_backend_rpc_add_server_t ) ggml_backend_reg_get_proc_address ( rpc_reg , "ggml_backend_rpc_add_server" );
if ( ! ggml_backend_rpc_add_server_fn ) {
throw std :: invalid_argument ( "failed to find RPC add server function" );
2025-01-17 10:57:09 +02:00
}
for ( const auto & server : rpc_servers ) {
2025-10-04 12:49:16 +03:00
auto reg = ggml_backend_rpc_add_server_fn ( server . c_str ());
ggml_backend_register ( reg );
2025-01-17 10:57:09 +02:00
}
}
2024-10-10 22:57:42 +02:00
bool common_params_parse ( int argc , char ** argv , common_params & params , llama_example ex , void ( * print_usage )( int , char ** )) {
auto ctx_arg = common_params_parser_init ( params , ex , print_usage );
const common_params params_org = ctx_arg . params ; // the example can modify the default params
2024-09-09 23:36:09 +02:00
try {
2024-10-10 22:57:42 +02:00
if ( ! common_params_parse_ex ( argc , argv , ctx_arg )) {
2024-09-09 23:36:09 +02:00
ctx_arg . params = params_org ;
return false ;
}
if ( ctx_arg . params . usage ) {
2024-10-10 22:57:42 +02:00
common_params_print_usage ( ctx_arg );
2024-09-09 23:36:09 +02:00
if ( ctx_arg . print_usage ) {
ctx_arg . print_usage ( argc , argv );
}
exit ( 0 );
}
2025-02-13 14:46:59 +01:00
if ( ctx_arg . params . completion ) {
common_params_print_completion ( ctx_arg );
exit ( 0 );
}
2025-08-14 03:03:57 -07:00
params . lr . init ();
2024-09-09 23:36:09 +02:00
} catch ( const std :: invalid_argument & ex ) {
fprintf ( stderr , "%s \n " , ex . what ());
ctx_arg . params = params_org ;
return false ;
2025-04-30 10:46:32 +02:00
} catch ( std :: exception & ex ) {
fprintf ( stderr , "%s \n " , ex . what ());
exit ( 1 ); // for other exceptions, we exit with status code 1
2024-09-09 23:36:09 +02:00
}
return true ;
}
2024-12-02 22:10:19 +01:00
static std :: string list_builtin_chat_templates () {
std :: vector < const char *> supported_tmpl ;
int32_t res = llama_chat_builtin_templates ( nullptr , 0 );
supported_tmpl . resize ( res );
res = llama_chat_builtin_templates ( supported_tmpl . data (), supported_tmpl . size ());
std :: ostringstream msg ;
for ( auto & tmpl : supported_tmpl ) {
msg << tmpl << ( & tmpl == & supported_tmpl . back () ? "" : ", " );
}
return msg . str ();
}
2025-09-05 19:43:59 +01:00
static bool is_truthy ( const std :: string & value ) {
return value == "on" || value == "enabled" || value == "1" ;
}
static bool is_falsey ( const std :: string & value ) {
return value == "off" || value == "disabled" || value == "0" ;
}
static bool is_autoy ( const std :: string & value ) {
return value == "auto" || value == "-1" ;
}
2024-10-10 22:57:42 +02:00
common_params_context common_params_parser_init ( common_params & params , llama_example ex , void ( * print_usage )( int , char ** )) {
2024-11-25 19:30:06 +01:00
// load dynamic backends
ggml_backend_load_all ();
2024-10-10 22:57:42 +02:00
common_params_context ctx_arg ( params );
2024-09-09 23:36:09 +02:00
ctx_arg . print_usage = print_usage ;
ctx_arg . ex = ex ;
std :: string sampler_type_chars ;
std :: string sampler_type_names ;
2024-11-25 09:58:41 +02:00
for ( const auto & sampler : params . sampling . samplers ) {
2024-10-10 22:57:42 +02:00
sampler_type_chars += common_sampler_type_to_chr ( sampler );
sampler_type_names += common_sampler_type_to_str ( sampler ) + ";" ;
2024-09-09 23:36:09 +02:00
}
sampler_type_names . pop_back ();
/**
* filter options by example
* rules:
* - all examples inherit options from LLAMA_EXAMPLE_COMMON
* - if LLAMA_EXAMPLE_* is set (other than COMMON), we only show the option in the corresponding example
* - if both {LLAMA_EXAMPLE_COMMON, LLAMA_EXAMPLE_*,} are set, we will prioritize the LLAMA_EXAMPLE_* matching current example
*/
2024-10-10 22:57:42 +02:00
auto add_opt = [ & ]( common_arg arg ) {
2025-01-08 12:55:36 +02:00
if (( arg . in_example ( ex ) || arg . in_example ( LLAMA_EXAMPLE_COMMON )) && ! arg . is_exclude ( ex )) {
2024-09-09 23:36:09 +02:00
ctx_arg . options . push_back ( std :: move ( arg ));
}
};
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-h" , "--help" , "--usage" },
"print usage and exit" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . usage = true ;
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--version" },
"show version and build info" ,
2024-10-10 22:57:42 +02:00
[]( common_params & ) {
2024-09-09 23:36:09 +02:00
fprintf ( stderr , "version: %d (%s) \n " , LLAMA_BUILD_NUMBER , LLAMA_COMMIT );
fprintf ( stderr , "built with %s for %s \n " , LLAMA_COMPILER , LLAMA_BUILD_TARGET );
exit ( 0 );
}
));
2025-02-13 14:46:59 +01:00
add_opt ( common_arg (
{ "--completion-bash" },
"print source-able bash completion script for llama.cpp" ,
[]( common_params & params ) {
params . completion = true ;
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--verbose-prompt" },
2024-10-12 08:21:51 +03:00
string_format ( "print a verbose prompt before generation (default: %s)" , params . verbose_prompt ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . verbose_prompt = true ;
}
2024-09-28 17:42:03 +03:00
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--no-display-prompt" },
2024-10-12 08:21:51 +03:00
string_format ( "don't print prompt at generation (default: %s)" , ! params . display_prompt ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . display_prompt = false ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-co" , "--color" },
2024-10-12 08:21:51 +03:00
string_format ( "colorise output to distinguish prompt and user input from generations (default: %s)" , params . use_color ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . use_color = true ;
}
2025-05-07 10:28:02 +03:00
). set_examples ({ LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_LOOKUP }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-t" , "--threads" }, "N" ,
2025-10-16 01:11:33 -04:00
string_format ( "number of CPU threads to use during generation (default: %d)" , params . cpuparams . n_threads ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . cpuparams . n_threads = value ;
if ( params . cpuparams . n_threads <= 0 ) {
params . cpuparams . n_threads = std :: thread :: hardware_concurrency ();
}
}
). set_env ( "LLAMA_ARG_THREADS" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-tb" , "--threads-batch" }, "N" ,
"number of threads to use during batch and prompt processing (default: same as --threads)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . cpuparams_batch . n_threads = value ;
if ( params . cpuparams_batch . n_threads <= 0 ) {
params . cpuparams_batch . n_threads = std :: thread :: hardware_concurrency ();
}
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-C" , "--cpu-mask" }, "M" ,
"CPU affinity mask: arbitrarily long hex. Complements cpu-range (default: \"\" )" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & mask ) {
2024-09-09 23:36:09 +02:00
params . cpuparams . mask_valid = true ;
if ( ! parse_cpu_mask ( mask , params . cpuparams . cpumask )) {
throw std :: invalid_argument ( "invalid cpumask" );
}
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-Cr" , "--cpu-range" }, "lo-hi" ,
"range of CPUs for affinity. Complements --cpu-mask" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & range ) {
2024-09-09 23:36:09 +02:00
params . cpuparams . mask_valid = true ;
if ( ! parse_cpu_range ( range , params . cpuparams . cpumask )) {
throw std :: invalid_argument ( "invalid range" );
}
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--cpu-strict" }, "<0|1>" ,
2024-10-12 08:21:51 +03:00
string_format ( "use strict CPU placement (default: %u) \n " , ( unsigned ) params . cpuparams . strict_cpu ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . cpuparams . strict_cpu = std :: stoul ( value );
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--prio" }, "N" ,
2025-05-31 15:39:19 -07:00
string_format ( "set process/thread priority : low(-1), normal(0), medium(1), high(2), realtime(3) (default: %d) \n " , params . cpuparams . priority ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int prio ) {
2025-05-31 15:39:19 -07:00
if ( prio < GGML_SCHED_PRIO_LOW || prio > GGML_SCHED_PRIO_REALTIME ) {
2024-09-09 23:36:09 +02:00
throw std :: invalid_argument ( "invalid value" );
}
params . cpuparams . priority = ( enum ggml_sched_priority ) prio ;
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--poll" }, "<0...100>" ,
2024-10-12 08:21:51 +03:00
string_format ( "use polling level to wait for work (0 - no polling, default: %u) \n " , ( unsigned ) params . cpuparams . poll ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . cpuparams . poll = std :: stoul ( value );
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-Cb" , "--cpu-mask-batch" }, "M" ,
"CPU affinity mask: arbitrarily long hex. Complements cpu-range-batch (default: same as --cpu-mask)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & mask ) {
2024-09-09 23:36:09 +02:00
params . cpuparams_batch . mask_valid = true ;
if ( ! parse_cpu_mask ( mask , params . cpuparams_batch . cpumask )) {
throw std :: invalid_argument ( "invalid cpumask" );
}
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-Crb" , "--cpu-range-batch" }, "lo-hi" ,
"ranges of CPUs for affinity. Complements --cpu-mask-batch" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & range ) {
2024-09-09 23:36:09 +02:00
params . cpuparams_batch . mask_valid = true ;
if ( ! parse_cpu_range ( range , params . cpuparams_batch . cpumask )) {
throw std :: invalid_argument ( "invalid range" );
}
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--cpu-strict-batch" }, "<0|1>" ,
"use strict CPU placement (default: same as --cpu-strict)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . cpuparams_batch . strict_cpu = value ;
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--prio-batch" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "set process/thread priority : 0-normal, 1-medium, 2-high, 3-realtime (default: %d) \n " , params . cpuparams_batch . priority ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int prio ) {
2024-09-09 23:36:09 +02:00
if ( prio < 0 || prio > 3 ) {
throw std :: invalid_argument ( "invalid value" );
}
params . cpuparams_batch . priority = ( enum ggml_sched_priority ) prio ;
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--poll-batch" }, "<0|1>" ,
"use polling to wait for work (default: same as --poll)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . cpuparams_batch . poll = value ;
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-lcs" , "--lookup-cache-static" }, "FNAME" ,
"path to static lookup cache to use for lookup decoding (not updated by generation)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . lookup_cache_static = value ;
}
). set_examples ({ LLAMA_EXAMPLE_LOOKUP }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-lcd" , "--lookup-cache-dynamic" }, "FNAME" ,
"path to dynamic lookup cache to use for lookup decoding (updated by generation)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . lookup_cache_dynamic = value ;
}
). set_examples ({ LLAMA_EXAMPLE_LOOKUP }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-c" , "--ctx-size" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "size of the prompt context (default: %d, 0 = loaded from model)" , params . n_ctx ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_ctx = value ;
}
). set_env ( "LLAMA_ARG_CTX_SIZE" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-n" , "--predict" , "--n-predict" }, "N" ,
2025-03-13 12:34:54 +01:00
string_format (
2025-05-07 10:28:02 +03:00
ex == LLAMA_EXAMPLE_MAIN
2025-03-13 12:34:54 +01:00
? "number of tokens to predict (default: %d, -1 = infinity, -2 = until context filled)"
: "number of tokens to predict (default: %d, -1 = infinity)" ,
params . n_predict ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_predict = value ;
}
). set_env ( "LLAMA_ARG_N_PREDICT" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-b" , "--batch-size" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "logical maximum batch size (default: %d)" , params . n_batch ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_batch = value ;
}
). set_env ( "LLAMA_ARG_BATCH" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-ub" , "--ubatch-size" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "physical maximum batch size (default: %d)" , params . n_ubatch ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_ubatch = value ;
}
). set_env ( "LLAMA_ARG_UBATCH" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--keep" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "number of tokens to keep from the initial prompt (default: %d, -1 = all)" , params . n_keep ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_keep = value ;
}
));
2025-05-20 08:05:46 +03:00
add_opt ( common_arg (
{ "--swa-full" },
string_format ( "use full-size SWA cache (default: %s) \n "
"[(more info)](https://github.com/ggml-org/llama.cpp/pull/13194#issuecomment-2868343055)" , params . swa_full ? "true" : "false" ),
[]( common_params & params ) {
params . swa_full = true ;
}
2025-05-20 16:13:16 +03:00
). set_env ( "LLAMA_ARG_SWA_FULL" ));
2025-08-14 14:59:50 +03:00
add_opt ( common_arg (
2025-10-03 13:34:51 -05:00
{ "--ctx-checkpoints" , "--swa-checkpoints" }, "N" ,
string_format ( "max number of context checkpoints to create per slot (default: %d) \n "
"[(more info)](https://github.com/ggml-org/llama.cpp/pull/15293)" , params . n_ctx_checkpoints ),
2025-08-14 14:59:50 +03:00
[]( common_params & params , int value ) {
2025-10-03 13:34:51 -05:00
params . n_ctx_checkpoints = value ;
2025-08-14 14:59:50 +03:00
}
2025-10-03 13:34:51 -05:00
). set_env ( "LLAMA_ARG_CTX_CHECKPOINTS" ). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2025-10-09 18:54:51 +03:00
add_opt ( common_arg (
{ "--cache-ram" , "-cram" }, "N" ,
string_format ( "set the maximum cache size in MiB (default: %d, -1 - no limit, 0 - disable) \n "
"[(more info)](https://github.com/ggml-org/llama.cpp/pull/16391)" , params . cache_ram_mib ),
[]( common_params & params , int value ) {
params . cache_ram_mib = value ;
}
). set_env ( "LLAMA_ARG_CACHE_RAM" ). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2025-07-16 16:35:42 +03:00
add_opt ( common_arg (
{ "--kv-unified" , "-kvu" },
string_format ( "use single unified KV buffer for the KV cache of all sequences (default: %s) \n "
"[(more info)](https://github.com/ggml-org/llama.cpp/pull/14363)" , params . kv_unified ? "true" : "false" ),
[]( common_params & params ) {
params . kv_unified = true ;
}
). set_env ( "LLAMA_ARG_KV_SPLIT" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-16 01:20:01 -05:00
{ "--no-context-shift" },
2025-02-10 23:21:31 +01:00
string_format ( "disables context shift on infinite text generation (default: %s)" , params . ctx_shift ? "disabled" : "enabled" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-16 01:20:01 -05:00
params . ctx_shift = false ;
}
2024-12-20 17:44:58 +08:00
). set_examples ({ LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_SERVER , LLAMA_EXAMPLE_IMATRIX , LLAMA_EXAMPLE_PERPLEXITY }). set_env ( "LLAMA_ARG_NO_CONTEXT_SHIFT" ));
2025-08-19 16:46:37 +03:00
add_opt ( common_arg (
{ "--context-shift" },
2025-08-20 18:33:30 +08:00
string_format ( "enables context shift on infinite text generation (default: %s)" , params . ctx_shift ? "enabled" : "disabled" ),
2025-08-19 16:46:37 +03:00
[]( common_params & params ) {
params . ctx_shift = true ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_SERVER , LLAMA_EXAMPLE_IMATRIX , LLAMA_EXAMPLE_PERPLEXITY }). set_env ( "LLAMA_ARG_CONTEXT_SHIFT" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--chunks" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "max number of chunks to process (default: %d, -1 = all)" , params . n_chunks ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_chunks = value ;
}
). set_examples ({ LLAMA_EXAMPLE_IMATRIX , LLAMA_EXAMPLE_PERPLEXITY , LLAMA_EXAMPLE_RETRIEVAL }));
2025-09-05 19:43:59 +01:00
add_opt ( common_arg ({ "-fa" , "--flash-attn" }, "[on|off|auto]" ,
string_format ( "set Flash Attention use ('on', 'off', or 'auto', default: '%s')" ,
llama_flash_attn_type_name ( params . flash_attn_type )),
[]( common_params & params , const std :: string & value ) {
if ( is_truthy ( value )) {
params . flash_attn_type = LLAMA_FLASH_ATTN_TYPE_ENABLED ;
} else if ( is_falsey ( value )) {
params . flash_attn_type = LLAMA_FLASH_ATTN_TYPE_DISABLED ;
} else if ( is_autoy ( value )) {
params . flash_attn_type = LLAMA_FLASH_ATTN_TYPE_AUTO ;
} else {
throw std :: runtime_error (
string_format ( "error: unkown value for --flash-attn: '%s' \n " , value . c_str ()));
}
}). set_env ( "LLAMA_ARG_FLASH_ATTN" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-p" , "--prompt" }, "PROMPT" ,
2025-03-01 13:56:45 +01:00
"prompt to start generation with; for system message, use -sys" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . prompt = value ;
}
2025-01-08 12:55:36 +02:00
). set_excludes ({ LLAMA_EXAMPLE_SERVER }));
2025-03-01 13:56:45 +01:00
add_opt ( common_arg (
{ "-sys" , "--system-prompt" }, "PROMPT" ,
"system prompt to use with model (if applicable, depending on chat template)" ,
[]( common_params & params , const std :: string & value ) {
params . system_prompt = value ;
}
2025-09-16 10:38:28 +08:00
). set_examples ({ LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_DIFFUSION }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-13 09:53:38 +03:00
{ "--no-perf" },
2024-10-12 08:21:51 +03:00
string_format ( "disable internal libllama performance timings (default: %s)" , params . no_perf ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-13 09:53:38 +03:00
params . no_perf = true ;
2024-11-25 09:58:41 +02:00
params . sampling . no_perf = true ;
2024-09-13 09:53:38 +03:00
}
). set_env ( "LLAMA_ARG_NO_PERF" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-f" , "--file" }, "FNAME" ,
"a file containing the prompt (default: none)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2025-04-30 10:46:32 +02:00
params . prompt = read_file ( value );
2024-09-09 23:36:09 +02:00
// store the external file name in params
params . prompt_file = value ;
if ( ! params . prompt . empty () && params . prompt . back () == '\n' ) {
params . prompt . pop_back ();
}
}
2025-01-08 12:55:36 +02:00
). set_excludes ({ LLAMA_EXAMPLE_SERVER }));
2025-03-14 16:57:05 +01:00
add_opt ( common_arg (
{ "-sysf" , "--system-prompt-file" }, "FNAME" ,
"a file containing the system prompt (default: none)" ,
[]( common_params & params , const std :: string & value ) {
2025-04-30 10:46:32 +02:00
params . system_prompt = read_file ( value );
2025-03-14 16:57:05 +01:00
if ( ! params . system_prompt . empty () && params . system_prompt . back () == '\n' ) {
params . system_prompt . pop_back ();
}
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--in-file" }, "FNAME" ,
"an input file (repeat to specify multiple files)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
std :: ifstream file ( value );
if ( ! file ) {
2024-10-12 08:21:51 +03:00
throw std :: runtime_error ( string_format ( "error: failed to open file '%s' \n " , value . c_str ()));
2024-09-09 23:36:09 +02:00
}
params . in_files . push_back ( value );
}
). set_examples ({ LLAMA_EXAMPLE_IMATRIX }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-bf" , "--binary-file" }, "FNAME" ,
"binary file containing the prompt (default: none)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
std :: ifstream file ( value , std :: ios :: binary );
if ( ! file ) {
2024-10-12 08:21:51 +03:00
throw std :: runtime_error ( string_format ( "error: failed to open file '%s' \n " , value . c_str ()));
2024-09-09 23:36:09 +02:00
}
// store the external file name in params
params . prompt_file = value ;
std :: ostringstream ss ;
ss << file . rdbuf ();
params . prompt = ss . str ();
fprintf ( stderr , "Read %zu bytes from binary file %s \n " , params . prompt . size (), value . c_str ());
}
2025-01-08 12:55:36 +02:00
). set_excludes ({ LLAMA_EXAMPLE_SERVER }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-e" , "--escape" },
2024-10-12 08:21:51 +03:00
string_format ( "process escapes sequences ( \\ n, \\ r, \\ t, \\ ', \\\" , \\\\ ) (default: %s)" , params . escape ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . escape = true ;
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--no-escape" },
"do not process escape sequences" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . escape = false ;
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-ptc" , "--print-token-count" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "print token count every N tokens (default: %d)" , params . n_print ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_print = value ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--prompt-cache" }, "FNAME" ,
"file to cache prompt state for faster startup (default: none)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . path_prompt_cache = value ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--prompt-cache-all" },
"if specified, saves user input and generations to cache as well \n " ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . prompt_cache_all = true ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--prompt-cache-ro" },
"if specified, uses the prompt cache but does not update it" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . prompt_cache_ro = true ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-r" , "--reverse-prompt" }, "PROMPT" ,
"halt generation at PROMPT, return control in interactive mode \n " ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . antiprompt . emplace_back ( value );
}
2025-07-22 09:24:22 +08:00
). set_examples ({ LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_SERVER }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-sp" , "--special" },
2024-10-12 08:21:51 +03:00
string_format ( "special tokens output enabled (default: %s)" , params . special ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . special = true ;
}
2024-09-10 22:40:59 +02:00
). set_examples ({ LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_SERVER }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-cnv" , "--conversation" },
2025-01-13 20:18:12 +01:00
"run in conversation mode: \n "
"- does not print special tokens and suffix/prefix \n "
"- interactive mode is also enabled \n "
"(default: auto enabled if chat template is available)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2025-01-13 20:18:12 +01:00
params . conversation_mode = COMMON_CONVERSATION_MODE_ENABLED ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
add_opt ( common_arg (
{ "-no-cnv" , "--no-conversation" },
"force disable conversation mode (default: false)" ,
[]( common_params & params ) {
params . conversation_mode = COMMON_CONVERSATION_MODE_DISABLED ;
2024-09-09 23:36:09 +02:00
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2025-03-04 17:19:39 +01:00
add_opt ( common_arg (
{ "-st" , "--single-turn" },
"run conversation for a single turn only, then exit when done \n "
"will not be interactive if first turn is predefined with --prompt \n "
"(default: false)" ,
[]( common_params & params ) {
params . single_turn = true ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-i" , "--interactive" },
2024-10-12 08:21:51 +03:00
string_format ( "run in interactive mode (default: %s)" , params . interactive ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . interactive = true ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-if" , "--interactive-first" },
2024-10-12 08:21:51 +03:00
string_format ( "run in interactive mode and wait for input right away (default: %s)" , params . interactive_first ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . interactive_first = true ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-mli" , "--multiline-input" },
"allows you to write or paste multiple lines without ending each in ' \\ '" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . multiline_input = true ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--in-prefix-bos" },
"prefix BOS to user inputs, preceding the `--in-prefix` string" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . input_prefix_bos = true ;
params . enable_chat_template = false ;
}
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--in-prefix" }, "STRING" ,
"string to prefix user inputs with (default: empty)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . input_prefix = value ;
params . enable_chat_template = false ;
}
2025-05-07 10:28:02 +03:00
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--in-suffix" }, "STRING" ,
"string to suffix after user inputs with (default: empty)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . input_suffix = value ;
params . enable_chat_template = false ;
}
2025-05-07 10:28:02 +03:00
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--no-warmup" },
"skip warming up the model with an empty run" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . warmup = false ;
}
2025-08-21 14:09:32 -07:00
). set_examples ({ LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_SERVER , LLAMA_EXAMPLE_EMBEDDING , LLAMA_EXAMPLE_RETRIEVAL , LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--spm-infill" },
2024-10-12 08:21:51 +03:00
string_format (
2024-09-09 23:36:09 +02:00
"use Suffix/Prefix/Middle pattern for infill (instead of Prefix/Suffix/Middle) as some models prefer this. (default: %s)" ,
params . spm_infill ? "enabled" : "disabled"
),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . spm_infill = true ;
}
2025-05-07 10:28:02 +03:00
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--samplers" }, "SAMPLERS" ,
2024-10-12 08:21:51 +03:00
string_format ( "samplers that will be used for generation in the order, separated by \' ; \'\n (default: %s)" , sampler_type_names . c_str ()),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-10-25 17:57:54 +02:00
const auto sampler_names = string_split < std :: string > ( value , ';' );
2024-11-25 09:58:41 +02:00
params . sampling . samplers = common_sampler_types_from_names ( sampler_names , true );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-s" , "--seed" }, "SEED" ,
2024-11-25 09:58:41 +02:00
string_format ( "RNG seed (default: %d, use random seed for %d)" , params . sampling . seed , LLAMA_DEFAULT_SEED ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . seed = std :: stoul ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-12-18 19:27:21 +02:00
{ "--sampling-seq" , "--sampler-seq" }, "SEQUENCE" ,
2024-10-12 08:21:51 +03:00
string_format ( "simplified sequence for samplers that will be used (default: %s)" , sampler_type_chars . c_str ()),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . samplers = common_sampler_types_from_chars ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--ignore-eos" },
"ignore end of stream token and continue generating (implies --logit-bias EOS-inf)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-11-25 09:58:41 +02:00
params . sampling . ignore_eos = true ;
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--temp" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "temperature (default: %.1f)" , ( double ) params . sampling . temp ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . temp = std :: stof ( value );
params . sampling . temp = std :: max ( params . sampling . temp , 0.0f );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--top-k" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "top-k sampling (default: %d, 0 = disabled)" , params . sampling . top_k ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-11-25 09:58:41 +02:00
params . sampling . top_k = value ;
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--top-p" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "top-p sampling (default: %.1f, 1.0 = disabled)" , ( double ) params . sampling . top_p ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . top_p = std :: stof ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--min-p" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "min-p sampling (default: %.1f, 0.0 = disabled)" , ( double ) params . sampling . min_p ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . min_p = std :: stof ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2025-02-13 00:45:57 -06:00
add_opt ( common_arg (
{ "--top-nsigma" }, "N" ,
string_format ( "top-n-sigma sampling (default: %.1f, -1.0 = disabled)" , params . sampling . top_n_sigma ),
[]( common_params & params , const std :: string & value ) {
params . sampling . top_n_sigma = std :: stof ( value );
}
2025-08-19 18:58:14 +02:00
). set_sparam ());
2024-10-15 15:54:55 +05:00
add_opt ( common_arg (
{ "--xtc-probability" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "xtc probability (default: %.1f, 0.0 = disabled)" , ( double ) params . sampling . xtc_probability ),
2024-10-15 15:54:55 +05:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . xtc_probability = std :: stof ( value );
2024-10-15 15:54:55 +05:00
}
). set_sparam ());
add_opt ( common_arg (
{ "--xtc-threshold" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "xtc threshold (default: %.1f, 1.0 = disabled)" , ( double ) params . sampling . xtc_threshold ),
2024-10-15 15:54:55 +05:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . xtc_threshold = std :: stof ( value );
2024-10-15 15:54:55 +05:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--typical" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "locally typical sampling, parameter p (default: %.1f, 1.0 = disabled)" , ( double ) params . sampling . typ_p ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . typ_p = std :: stof ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--repeat-last-n" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "last n tokens to consider for penalize (default: %d, 0 = disabled, -1 = ctx_size)" , params . sampling . penalty_last_n ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-12-16 12:31:14 +02:00
if ( value < - 1 ) {
throw std :: runtime_error ( string_format ( "error: invalid repeat-last-n = %d \n " , value ));
}
2024-11-25 09:58:41 +02:00
params . sampling . penalty_last_n = value ;
params . sampling . n_prev = std :: max ( params . sampling . n_prev , params . sampling . penalty_last_n );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--repeat-penalty" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "penalize repeat sequence of tokens (default: %.1f, 1.0 = disabled)" , ( double ) params . sampling . penalty_repeat ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . penalty_repeat = std :: stof ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--presence-penalty" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "repeat alpha presence penalty (default: %.1f, 0.0 = disabled)" , ( double ) params . sampling . penalty_present ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . penalty_present = std :: stof ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--frequency-penalty" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "repeat alpha frequency penalty (default: %.1f, 0.0 = disabled)" , ( double ) params . sampling . penalty_freq ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . penalty_freq = std :: stof ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-25 10:07:34 -06:00
add_opt ( common_arg (
{ "--dry-multiplier" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "set DRY sampling multiplier (default: %.1f, 0.0 = disabled)" , ( double ) params . sampling . dry_multiplier ),
2024-10-25 10:07:34 -06:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . dry_multiplier = std :: stof ( value );
2024-10-25 10:07:34 -06:00
}
). set_sparam ());
add_opt ( common_arg (
{ "--dry-base" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "set DRY sampling base value (default: %.2f)" , ( double ) params . sampling . dry_base ),
2024-10-25 10:07:34 -06:00
[]( common_params & params , const std :: string & value ) {
float potential_base = std :: stof ( value );
if ( potential_base >= 1.0f )
{
2024-11-25 09:58:41 +02:00
params . sampling . dry_base = potential_base ;
2024-10-25 10:07:34 -06:00
}
}
). set_sparam ());
add_opt ( common_arg (
{ "--dry-allowed-length" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "set allowed length for DRY sampling (default: %d)" , params . sampling . dry_allowed_length ),
2024-10-25 10:07:34 -06:00
[]( common_params & params , int value ) {
2024-11-25 09:58:41 +02:00
params . sampling . dry_allowed_length = value ;
2024-10-25 10:07:34 -06:00
}
). set_sparam ());
add_opt ( common_arg (
{ "--dry-penalty-last-n" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "set DRY penalty for the last n tokens (default: %d, 0 = disable, -1 = context size)" , params . sampling . dry_penalty_last_n ),
2024-10-25 10:07:34 -06:00
[]( common_params & params , int value ) {
2024-12-16 12:31:14 +02:00
if ( value < - 1 ) {
throw std :: runtime_error ( string_format ( "error: invalid dry-penalty-last-n = %d \n " , value ));
}
2024-11-25 09:58:41 +02:00
params . sampling . dry_penalty_last_n = value ;
2024-10-25 10:07:34 -06:00
}
). set_sparam ());
add_opt ( common_arg (
{ "--dry-sequence-breaker" }, "STRING" ,
string_format ( "add sequence breaker for DRY sampling, clearing out default breakers (%s) in the process; use \" none \" to not use any sequence breakers \n " ,
2024-11-25 09:58:41 +02:00
params . sampling . dry_sequence_breakers . empty () ? "none" :
std :: accumulate ( std :: next ( params . sampling . dry_sequence_breakers . begin ()),
params . sampling . dry_sequence_breakers . end (),
std :: string ( "'" ) + ( params . sampling . dry_sequence_breakers [ 0 ] == " \n " ? " \\ n" : params . sampling . dry_sequence_breakers [ 0 ]) + "'" ,
2024-10-25 10:07:34 -06:00
[]( const std :: string & a , const std :: string & b ) {
std :: string formatted_b = ( b == " \n " ) ? " \\ n" : b ;
return a + ", '" + formatted_b + "'" ;
}). c_str ()),
[]( common_params & params , const std :: string & value ) {
static bool defaults_cleared = false ;
if ( ! defaults_cleared ) {
2024-11-25 09:58:41 +02:00
params . sampling . dry_sequence_breakers . clear ();
2024-10-25 10:07:34 -06:00
defaults_cleared = true ;
}
if ( value == "none" ) {
2024-11-25 09:58:41 +02:00
params . sampling . dry_sequence_breakers . clear ();
2024-10-25 10:07:34 -06:00
} else {
2024-11-25 09:58:41 +02:00
params . sampling . dry_sequence_breakers . emplace_back ( value );
2024-10-25 10:07:34 -06:00
}
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--dynatemp-range" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "dynamic temperature range (default: %.1f, 0.0 = disabled)" , ( double ) params . sampling . dynatemp_range ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . dynatemp_range = std :: stof ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--dynatemp-exp" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "dynamic temperature exponent (default: %.1f)" , ( double ) params . sampling . dynatemp_exponent ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . dynatemp_exponent = std :: stof ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--mirostat" }, "N" ,
2024-10-29 10:42:05 +02:00
string_format ( "use Mirostat sampling. \n Top K, Nucleus and Locally Typical samplers are ignored if used. \n "
2024-11-25 09:58:41 +02:00
"(default: %d, 0 = disabled, 1 = Mirostat, 2 = Mirostat 2.0)" , params . sampling . mirostat ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-11-25 09:58:41 +02:00
params . sampling . mirostat = value ;
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--mirostat-lr" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "Mirostat learning rate, parameter eta (default: %.1f)" , ( double ) params . sampling . mirostat_eta ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . mirostat_eta = std :: stof ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--mirostat-ent" }, "N" ,
2024-11-25 09:58:41 +02:00
string_format ( "Mirostat target entropy, parameter tau (default: %.1f)" , ( double ) params . sampling . mirostat_tau ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . mirostat_tau = std :: stof ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-l" , "--logit-bias" }, "TOKEN_ID(+/-)BIAS" ,
"modifies the likelihood of token appearing in the completion, \n "
"i.e. `--logit-bias 15043+1` to increase likelihood of token ' Hello', \n "
"or `--logit-bias 15043-1` to decrease likelihood of token ' Hello'" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
std :: stringstream ss ( value );
llama_token key ;
char sign ;
std :: string value_str ;
try {
if ( ss >> key && ss >> sign && std :: getline ( ss , value_str ) && ( sign == '+' || sign == '-' )) {
const float bias = std :: stof ( value_str ) * (( sign == '-' ) ? - 1.0f : 1.0f );
2024-11-25 09:58:41 +02:00
params . sampling . logit_bias . push_back ({ key , bias });
2024-09-09 23:36:09 +02:00
} else {
throw std :: invalid_argument ( "invalid input format" );
}
} catch ( const std :: exception & ) {
throw std :: invalid_argument ( "invalid input format" );
}
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--grammar" }, "GRAMMAR" ,
2024-11-25 09:58:41 +02:00
string_format ( "BNF-like grammar to constrain generations (see samples in grammars/ dir) (default: '%s')" , params . sampling . grammar . c_str ()),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . grammar = value ;
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--grammar-file" }, "FNAME" ,
"file to read grammar from" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2025-04-30 10:46:32 +02:00
params . sampling . grammar = read_file ( value );
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-j" , "--json-schema" }, "SCHEMA" ,
"JSON schema to constrain generations (https://json-schema.org/), e.g. `{}` for any JSON object \n For schemas w/ external $refs, use --grammar + example/json_schema_to_grammar.py instead" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-11-25 09:58:41 +02:00
params . sampling . grammar = json_schema_to_grammar ( json :: parse ( value ));
2024-09-09 23:36:09 +02:00
}
). set_sparam ());
2025-04-30 13:52:35 +01:00
add_opt ( common_arg (
{ "-jf" , "--json-schema-file" }, "FILE" ,
"File containing a JSON schema to constrain generations (https://json-schema.org/), e.g. `{}` for any JSON object \n For schemas w/ external $refs, use --grammar + example/json_schema_to_grammar.py instead" ,
[]( common_params & params , const std :: string & value ) {
std :: ifstream file ( value );
if ( ! file ) {
throw std :: runtime_error ( string_format ( "error: failed to open file '%s' \n " , value . c_str ()));
}
std :: string schema ;
std :: copy (
std :: istreambuf_iterator < char > ( file ),
std :: istreambuf_iterator < char > (),
std :: back_inserter ( schema )
);
params . sampling . grammar = json_schema_to_grammar ( json :: parse ( schema ));
}
). set_sparam ());
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-28 17:42:03 +03:00
{ "--pooling" }, "{none,mean,cls,last,rank}" ,
2024-09-09 23:36:09 +02:00
"pooling type for embeddings, use model default if unspecified" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
/**/ if ( value == "none" ) { params . pooling_type = LLAMA_POOLING_TYPE_NONE ; }
else if ( value == "mean" ) { params . pooling_type = LLAMA_POOLING_TYPE_MEAN ; }
2024-09-28 17:42:03 +03:00
else if ( value == "cls" ) { params . pooling_type = LLAMA_POOLING_TYPE_CLS ; }
2024-09-09 23:36:09 +02:00
else if ( value == "last" ) { params . pooling_type = LLAMA_POOLING_TYPE_LAST ; }
2024-09-28 17:42:03 +03:00
else if ( value == "rank" ) { params . pooling_type = LLAMA_POOLING_TYPE_RANK ; }
2024-09-09 23:36:09 +02:00
else { throw std :: invalid_argument ( "invalid value" ); }
}
2024-09-25 14:05:13 +02:00
). set_examples ({ LLAMA_EXAMPLE_EMBEDDING , LLAMA_EXAMPLE_RETRIEVAL , LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_POOLING" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-10-21 20:12:52 +02:00
{ "--attention" }, "{causal,non-causal}" ,
2024-09-09 23:36:09 +02:00
"attention type for embeddings, use model default if unspecified" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
/**/ if ( value == "causal" ) { params . attention_type = LLAMA_ATTENTION_TYPE_CAUSAL ; }
else if ( value == "non-causal" ) { params . attention_type = LLAMA_ATTENTION_TYPE_NON_CAUSAL ; }
else { throw std :: invalid_argument ( "invalid value" ); }
}
). set_examples ({ LLAMA_EXAMPLE_EMBEDDING }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--rope-scaling" }, "{none,linear,yarn}" ,
"RoPE frequency scaling method, defaults to linear unless specified by the model" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
/**/ if ( value == "none" ) { params . rope_scaling_type = LLAMA_ROPE_SCALING_TYPE_NONE ; }
else if ( value == "linear" ) { params . rope_scaling_type = LLAMA_ROPE_SCALING_TYPE_LINEAR ; }
else if ( value == "yarn" ) { params . rope_scaling_type = LLAMA_ROPE_SCALING_TYPE_YARN ; }
else { throw std :: invalid_argument ( "invalid value" ); }
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_ROPE_SCALING_TYPE" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--rope-scale" }, "N" ,
"RoPE context scaling factor, expands context by a factor of N" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . rope_freq_scale = 1.0f / std :: stof ( value );
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_ROPE_SCALE" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--rope-freq-base" }, "N" ,
"RoPE base frequency, used by NTK-aware scaling (default: loaded from model)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . rope_freq_base = std :: stof ( value );
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_ROPE_FREQ_BASE" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--rope-freq-scale" }, "N" ,
"RoPE frequency scaling factor, expands context by a factor of 1/N" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . rope_freq_scale = std :: stof ( value );
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_ROPE_FREQ_SCALE" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--yarn-orig-ctx" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "YaRN: original context size of model (default: %d = model training context size)" , params . yarn_orig_ctx ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . yarn_orig_ctx = value ;
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_YARN_ORIG_CTX" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--yarn-ext-factor" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "YaRN: extrapolation mix factor (default: %.1f, 0.0 = full interpolation)" , ( double ) params . yarn_ext_factor ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . yarn_ext_factor = std :: stof ( value );
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_YARN_EXT_FACTOR" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--yarn-attn-factor" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "YaRN: scale sqrt(t) or attention magnitude (default: %.1f)" , ( double ) params . yarn_attn_factor ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . yarn_attn_factor = std :: stof ( value );
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_YARN_ATTN_FACTOR" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--yarn-beta-slow" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "YaRN: high correction dim or alpha (default: %.1f)" , ( double ) params . yarn_beta_slow ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . yarn_beta_slow = std :: stof ( value );
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_YARN_BETA_SLOW" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--yarn-beta-fast" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "YaRN: low correction dim or beta (default: %.1f)" , ( double ) params . yarn_beta_fast ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . yarn_beta_fast = std :: stof ( value );
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_YARN_BETA_FAST" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-gan" , "--grp-attn-n" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "group-attention factor (default: %d)" , params . grp_attn_n ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . grp_attn_n = value ;
}
2024-10-12 16:06:31 +03:00
). set_env ( "LLAMA_ARG_GRP_ATTN_N" ). set_examples ({ LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_PASSKEY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-gaw" , "--grp-attn-w" }, "N" ,
2024-10-12 16:06:31 +03:00
string_format ( "group-attention width (default: %d)" , params . grp_attn_w ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . grp_attn_w = value ;
}
2024-10-12 16:06:31 +03:00
). set_env ( "LLAMA_ARG_GRP_ATTN_W" ). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-nkvo" , "--no-kv-offload" },
"disable KV offload" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . no_kv_offload = true ;
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_NO_KV_OFFLOAD" ));
2025-07-31 09:11:34 -07:00
add_opt ( common_arg (
{ "-nr" , "--no-repack" },
"disable weight repacking" ,
[]( common_params & params ) {
params . no_extra_bufts = true ;
}
). set_env ( "LLAMA_ARG_NO_REPACK" ));
2025-10-06 12:55:53 -05:00
add_opt ( common_arg (
{ "--no-host" },
"bypass host buffer allowing extra buffers to be used" ,
[]( common_params & params ) {
params . no_host = true ;
}
). set_env ( "LLAMA_ARG_NO_HOST" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-ctk" , "--cache-type-k" }, "TYPE" ,
2024-12-12 22:53:05 +01:00
string_format (
"KV cache data type for K \n "
"allowed values: %s \n "
"(default: %s)" ,
get_all_kv_cache_types (). c_str (),
ggml_type_name ( params . cache_type_k )
),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-12-12 22:53:05 +01:00
params . cache_type_k = kv_cache_type_from_str ( value );
2024-09-09 23:36:09 +02:00
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_CACHE_TYPE_K" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-ctv" , "--cache-type-v" }, "TYPE" ,
2024-12-12 22:53:05 +01:00
string_format (
"KV cache data type for V \n "
"allowed values: %s \n "
"(default: %s)" ,
get_all_kv_cache_types (). c_str (),
ggml_type_name ( params . cache_type_v )
),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-12-12 22:53:05 +01:00
params . cache_type_v = kv_cache_type_from_str ( value );
2024-09-09 23:36:09 +02:00
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_CACHE_TYPE_V" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--hellaswag" },
"compute HellaSwag score over random tasks from datafile supplied with -f" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . hellaswag = true ;
}
). set_examples ({ LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--hellaswag-tasks" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "number of tasks to use when computing the HellaSwag score (default: %zu)" , params . hellaswag_tasks ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . hellaswag_tasks = value ;
}
). set_examples ({ LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--winogrande" },
"compute Winogrande score over random tasks from datafile supplied with -f" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . winogrande = true ;
}
). set_examples ({ LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--winogrande-tasks" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "number of tasks to use when computing the Winogrande score (default: %zu)" , params . winogrande_tasks ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . winogrande_tasks = value ;
}
). set_examples ({ LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--multiple-choice" },
"compute multiple choice score over random tasks from datafile supplied with -f" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . multiple_choice = true ;
}
). set_examples ({ LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--multiple-choice-tasks" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "number of tasks to use when computing the multiple choice score (default: %zu)" , params . multiple_choice_tasks ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . multiple_choice_tasks = value ;
}
). set_examples ({ LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--kl-divergence" },
"computes KL-divergence to logits provided via --kl-divergence-base" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . kl_divergence = true ;
}
). set_examples ({ LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--save-all-logits" , "--kl-divergence-base" }, "FNAME" ,
"set logits file" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . logits_file = value ;
}
). set_examples ({ LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--ppl-stride" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "stride for perplexity calculation (default: %d)" , params . ppl_stride ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . ppl_stride = value ;
}
). set_examples ({ LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--ppl-output-type" }, "<0|1>" ,
2024-10-12 08:21:51 +03:00
string_format ( "output type for perplexity calculation (default: %d)" , params . ppl_output_type ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . ppl_output_type = value ;
}
). set_examples ({ LLAMA_EXAMPLE_PERPLEXITY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-dt" , "--defrag-thold" }, "N" ,
2025-08-22 12:22:13 +03:00
string_format ( "KV cache defragmentation threshold (DEPRECATED)" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2025-08-22 12:22:13 +03:00
GGML_UNUSED ( params );
GGML_UNUSED ( value );
LOG_WRN ( "DEPRECATED: --defrag-thold is deprecated and no longer necessary to specify \n " );
2024-09-09 23:36:09 +02:00
}
). set_env ( "LLAMA_ARG_DEFRAG_THOLD" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-np" , "--parallel" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "number of parallel sequences to decode (default: %d)" , params . n_parallel ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_parallel = value ;
}
2024-09-17 09:35:38 -04:00
). set_env ( "LLAMA_ARG_N_PARALLEL" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-ns" , "--sequences" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "number of sequences to decode (default: %d)" , params . n_sequences ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_sequences = value ;
}
). set_examples ({ LLAMA_EXAMPLE_PARALLEL }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-cb" , "--cont-batching" },
2024-10-12 08:21:51 +03:00
string_format ( "enable continuous batching (a.k.a dynamic batching) (default: %s)" , params . cont_batching ? "enabled" : "disabled" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . cont_batching = true ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_CONT_BATCHING" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-nocb" , "--no-cont-batching" },
"disable continuous batching" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . cont_batching = false ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_NO_CONT_BATCHING" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--mmproj" }, "FILE" ,
2025-05-10 08:16:29 +02:00
"path to a multimodal projector file. see tools/mtmd/README.md \n "
"note: if -hf is used, this argument can be omitted" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2025-04-01 23:44:05 +02:00
params . mmproj . path = value ;
}
2025-05-10 08:16:29 +02:00
). set_examples ( mmproj_examples ). set_env ( "LLAMA_ARG_MMPROJ" ));
2025-04-01 23:44:05 +02:00
add_opt ( common_arg (
{ "--mmproj-url" }, "URL" ,
2025-05-05 16:02:55 +02:00
"URL to a multimodal projector file. see tools/mtmd/README.md" ,
2025-04-01 23:44:05 +02:00
[]( common_params & params , const std :: string & value ) {
params . mmproj . url = value ;
2024-09-09 23:36:09 +02:00
}
2025-05-10 08:16:29 +02:00
). set_examples ( mmproj_examples ). set_env ( "LLAMA_ARG_MMPROJ_URL" ));
2025-04-24 12:14:13 +02:00
add_opt ( common_arg (
{ "--no-mmproj" },
"explicitly disable multimodal projector, useful when using -hf" ,
[]( common_params & params ) {
params . no_mmproj = true ;
}
2025-05-10 08:16:29 +02:00
). set_examples ( mmproj_examples ). set_env ( "LLAMA_ARG_NO_MMPROJ" ));
2025-04-24 14:04:14 +02:00
add_opt ( common_arg (
{ "--no-mmproj-offload" },
"do not offload multimodal projector to GPU" ,
[]( common_params & params ) {
params . mmproj_use_gpu = false ;
}
2025-05-10 08:16:29 +02:00
). set_examples ( mmproj_examples ). set_env ( "LLAMA_ARG_NO_MMPROJ_OFFLOAD" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2025-05-22 20:42:48 +02:00
{ "--image" , "--audio" }, "FILE" ,
"path to an image or audio file. use with multimodal models, can be repeated if you have multiple files \n " ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . image . emplace_back ( value );
}
2025-05-22 20:42:48 +02:00
). set_examples ({ LLAMA_EXAMPLE_MTMD }));
2024-10-10 20:14:55 +02:00
if ( llama_supports_rpc ()) {
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-10-10 20:14:55 +02:00
{ "--rpc" }, "SERVERS" ,
"comma separated list of RPC servers" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2025-01-17 10:57:09 +02:00
add_rpc_devices ( value );
GGML_UNUSED ( params );
2024-10-10 20:14:55 +02:00
}
). set_env ( "LLAMA_ARG_RPC" ));
}
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--mlock" },
"force system to keep model in RAM rather than swapping or compressing" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . use_mlock = true ;
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_MLOCK" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--no-mmap" },
"do not memory-map model (slower load but may reduce pageouts if not using mlock)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . use_mmap = false ;
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_NO_MMAP" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--numa" }, "TYPE" ,
"attempt optimizations that help on some NUMA systems \n "
"- distribute: spread execution evenly over all nodes \n "
"- isolate: only spawn threads on CPUs on the node that execution started on \n "
"- numactl: use the CPU map provided by numactl \n "
"if run without this previously, it is recommended to drop the system page cache before using this \n "
2025-02-15 16:40:57 +02:00
"see https://github.com/ggml-org/llama.cpp/issues/1437" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
/**/ if ( value == "distribute" || value == "" ) { params . numa = GGML_NUMA_STRATEGY_DISTRIBUTE ; }
else if ( value == "isolate" ) { params . numa = GGML_NUMA_STRATEGY_ISOLATE ; }
else if ( value == "numactl" ) { params . numa = GGML_NUMA_STRATEGY_NUMACTL ; }
else { throw std :: invalid_argument ( "invalid value" ); }
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_NUMA" ));
2024-11-25 19:30:06 +01:00
add_opt ( common_arg (
{ "-dev" , "--device" }, "<dev1,dev2,..>" ,
"comma-separated list of devices to use for offloading (none = don't offload) \n "
"use --list-devices to see a list of available devices" ,
[]( common_params & params , const std :: string & value ) {
params . devices = parse_device_list ( value );
}
). set_env ( "LLAMA_ARG_DEVICE" ));
add_opt ( common_arg (
{ "--list-devices" },
"print list of available devices and exit" ,
[]( common_params & ) {
2025-09-13 07:49:49 -07:00
std :: vector < ggml_backend_dev_t > devices ;
2024-11-25 19:30:06 +01:00
for ( size_t i = 0 ; i < ggml_backend_dev_count (); ++ i ) {
auto * dev = ggml_backend_dev_get ( i );
2025-09-13 07:49:49 -07:00
if ( ggml_backend_dev_type ( dev ) != GGML_BACKEND_DEVICE_TYPE_CPU ) {
devices . push_back ( dev );
2024-11-25 19:30:06 +01:00
}
}
2025-02-04 18:16:20 +02:00
printf ( "Available devices: \n " );
2025-09-13 07:49:49 -07:00
for ( auto * dev : devices ) {
2025-02-04 18:16:20 +02:00
size_t free , total ;
ggml_backend_dev_memory ( dev , & free , & total );
printf ( " %s: %s (%zu MiB, %zu MiB free) \n " , ggml_backend_dev_name ( dev ), ggml_backend_dev_description ( dev ), total / 1024 / 1024 , free / 1024 / 1024 );
}
2024-11-25 19:30:06 +01:00
exit ( 0 );
}
));
2025-04-02 14:52:01 +02:00
add_opt ( common_arg (
{ "--override-tensor" , "-ot" }, "<tensor name pattern>=<buffer type>,..." ,
"override tensor buffer type" , []( common_params & params , const std :: string & value ) {
2025-08-13 12:44:40 +02:00
parse_tensor_buffer_overrides ( value , params . tensor_buft_overrides );
2025-04-02 14:52:01 +02:00
}
));
2025-08-13 12:44:40 +02:00
add_opt ( common_arg (
{ "--override-tensor-draft" , "-otd" }, "<tensor name pattern>=<buffer type>,..." ,
"override tensor buffer type for draft model" , []( common_params & params , const std :: string & value ) {
parse_tensor_buffer_overrides ( value , params . speculative . tensor_buft_overrides );
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }));
2025-07-31 11:15:41 -07:00
add_opt ( common_arg (
2025-08-04 16:05:36 -07:00
{ "--cpu-moe" , "-cmoe" },
"keep all Mixture of Experts (MoE) weights in the CPU" ,
2025-07-31 11:15:41 -07:00
[]( common_params & params ) {
2025-09-16 16:17:08 +02:00
params . tensor_buft_overrides . push_back ( llm_ffn_exps_cpu_override ());
2025-07-31 11:15:41 -07:00
}
). set_env ( "LLAMA_ARG_CPU_MOE" ));
2025-08-04 16:05:36 -07:00
add_opt ( common_arg (
{ "--n-cpu-moe" , "-ncmoe" }, "N" ,
"keep the Mixture of Experts (MoE) weights of the first N layers in the CPU" ,
[]( common_params & params , int value ) {
if ( value < 0 ) {
throw std :: invalid_argument ( "invalid value" );
}
for ( int i = 0 ; i < value ; ++ i ) {
// keep strings alive and avoid leaking memory by storing them in a static vector
static std :: list < std :: string > buft_overrides ;
2025-09-16 16:17:08 +02:00
buft_overrides . push_back ( llm_ffn_exps_block_regex ( i ));
2025-08-04 16:05:36 -07:00
params . tensor_buft_overrides . push_back ({ buft_overrides . back (). c_str (), ggml_backend_cpu_buffer_type ()});
}
}
). set_env ( "LLAMA_ARG_N_CPU_MOE" ));
2025-08-13 12:44:40 +02:00
add_opt ( common_arg (
{ "--cpu-moe-draft" , "-cmoed" },
"keep all Mixture of Experts (MoE) weights in the CPU for the draft model" ,
[]( common_params & params ) {
2025-09-16 16:17:08 +02:00
params . speculative . tensor_buft_overrides . push_back ( llm_ffn_exps_cpu_override ());
2025-08-13 12:44:40 +02:00
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_CPU_MOE_DRAFT" ));
add_opt ( common_arg (
{ "--n-cpu-moe-draft" , "-ncmoed" }, "N" ,
"keep the Mixture of Experts (MoE) weights of the first N layers in the CPU for the draft model" ,
[]( common_params & params , int value ) {
if ( value < 0 ) {
throw std :: invalid_argument ( "invalid value" );
}
for ( int i = 0 ; i < value ; ++ i ) {
static std :: list < std :: string > buft_overrides_draft ;
2025-09-16 16:17:08 +02:00
buft_overrides_draft . push_back ( llm_ffn_exps_block_regex ( i ));
2025-08-13 12:44:40 +02:00
params . speculative . tensor_buft_overrides . push_back ({ buft_overrides_draft . back (). c_str (), ggml_backend_cpu_buffer_type ()});
}
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_N_CPU_MOE_DRAFT" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-ngl" , "--gpu-layers" , "--n-gpu-layers" }, "N" ,
2025-09-04 10:49:44 +01:00
string_format ( "max. number of layers to store in VRAM (default: %d)" , params . n_gpu_layers ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_gpu_layers = value ;
if ( ! llama_supports_gpu_offload ()) {
2024-11-28 18:15:25 +01:00
fprintf ( stderr , "warning: no usable GPU found, --gpu-layers option will be ignored \n " );
fprintf ( stderr , "warning: one possible reason is that llama.cpp was compiled without GPU support \n " );
fprintf ( stderr , "warning: consult docs/build.md for compilation instructions \n " );
2024-09-09 23:36:09 +02:00
}
}
). set_env ( "LLAMA_ARG_N_GPU_LAYERS" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-sm" , "--split-mode" }, "{none,layer,row}" ,
"how to split the model across multiple GPUs, one of: \n "
"- none: use one GPU only \n "
"- layer (default): split layers and KV across GPUs \n "
"- row: split rows across GPUs" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
std :: string arg_next = value ;
if ( arg_next == "none" ) {
params . split_mode = LLAMA_SPLIT_MODE_NONE ;
} else if ( arg_next == "layer" ) {
params . split_mode = LLAMA_SPLIT_MODE_LAYER ;
2024-09-10 22:41:29 +02:00
} else if ( arg_next == "row" ) {
2024-09-09 23:36:09 +02:00
params . split_mode = LLAMA_SPLIT_MODE_ROW ;
2024-09-10 22:41:29 +02:00
} else {
2024-09-09 23:36:09 +02:00
throw std :: invalid_argument ( "invalid value" );
}
2024-09-10 22:41:29 +02:00
if ( ! llama_supports_gpu_offload ()) {
fprintf ( stderr , "warning: llama.cpp was compiled without support for GPU offload. Setting the split mode has no effect. \n " );
}
2024-09-09 23:36:09 +02:00
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_SPLIT_MODE" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-ts" , "--tensor-split" }, "N0,N1,N2,..." ,
"fraction of the model to offload to each GPU, comma-separated list of proportions, e.g. 3,1" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
std :: string arg_next = value ;
// split string by , and /
const std :: regex regex { R "([,/]+)" };
std :: sregex_token_iterator it { arg_next . begin (), arg_next . end (), regex , - 1 };
std :: vector < std :: string > split_arg { it , {} };
if ( split_arg . size () >= llama_max_devices ()) {
throw std :: invalid_argument (
2024-10-12 08:21:51 +03:00
string_format ( "got %d input configs, but system only has %d devices" , ( int ) split_arg . size (), ( int ) llama_max_devices ())
2024-09-09 23:36:09 +02:00
);
}
for ( size_t i = 0 ; i < llama_max_devices (); ++ i ) {
if ( i < split_arg . size ()) {
2024-09-10 22:41:29 +02:00
params . tensor_split [ i ] = std :: stof ( split_arg [ i ]);
2024-09-09 23:36:09 +02:00
} else {
2024-09-10 22:41:29 +02:00
params . tensor_split [ i ] = 0.0f ;
2024-09-09 23:36:09 +02:00
}
}
2024-09-10 22:41:29 +02:00
if ( ! llama_supports_gpu_offload ()) {
fprintf ( stderr , "warning: llama.cpp was compiled without support for GPU offload. Setting a tensor split has no effect. \n " );
}
2024-09-09 23:36:09 +02:00
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_TENSOR_SPLIT" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-mg" , "--main-gpu" }, "INDEX" ,
2024-10-12 08:21:51 +03:00
string_format ( "the GPU to use for the model (with split-mode = none), or for intermediate results and KV (with split-mode = row) (default: %d)" , params . main_gpu ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . main_gpu = value ;
2024-09-10 22:41:29 +02:00
if ( ! llama_supports_gpu_offload ()) {
fprintf ( stderr , "warning: llama.cpp was compiled without support for GPU offload. Setting the main GPU has no effect. \n " );
}
2024-09-09 23:36:09 +02:00
}
2024-09-25 14:05:13 +02:00
). set_env ( "LLAMA_ARG_MAIN_GPU" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--check-tensors" },
2024-10-12 08:21:51 +03:00
string_format ( "check model tensor data for invalid values (default: %s)" , params . check_tensors ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . check_tensors = true ;
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--override-kv" }, "KEY=TYPE:VALUE" ,
"advanced option to override model metadata by key. may be specified multiple times. \n "
"types: int, float, bool, str. example: --override-kv tokenizer.ggml.add_bos_token=bool:false" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
if ( ! string_parse_kv_override ( value . c_str (), params . kv_overrides )) {
2024-10-12 08:21:51 +03:00
throw std :: runtime_error ( string_format ( "error: Invalid type for KV override: %s \n " , value . c_str ()));
2024-09-09 23:36:09 +02:00
}
}
));
2025-05-11 20:18:39 +08:00
add_opt ( common_arg (
{ "--no-op-offload" },
string_format ( "disable offloading host tensor operations to device (default: %s)" , params . no_op_offload ? "true" : "false" ),
[]( common_params & params ) {
params . no_op_offload = true ;
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--lora" }, "FNAME" ,
"path to LoRA adapter (can be repeated to use multiple adapters)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2025-08-28 15:49:50 +02:00
params . lora_adapters . push_back ({ std :: string ( value ), 1.0 , "" , "" , nullptr });
2024-09-09 23:36:09 +02:00
}
// we define this arg on both COMMON and EXPORT_LORA, so when showing help message of export-lora, it will be categorized as "example-specific" arg
). set_examples ({ LLAMA_EXAMPLE_COMMON , LLAMA_EXAMPLE_EXPORT_LORA }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--lora-scaled" }, "FNAME" , "SCALE" ,
"path to LoRA adapter with user defined scaling (can be repeated to use multiple adapters)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & fname , const std :: string & scale ) {
2025-08-28 15:49:50 +02:00
params . lora_adapters . push_back ({ fname , std :: stof ( scale ), "" , "" , nullptr });
2024-09-09 23:36:09 +02:00
}
// we define this arg on both COMMON and EXPORT_LORA, so when showing help message of export-lora, it will be categorized as "example-specific" arg
). set_examples ({ LLAMA_EXAMPLE_COMMON , LLAMA_EXAMPLE_EXPORT_LORA }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--control-vector" }, "FNAME" ,
"add a control vector \n note: this argument can be repeated to add multiple control vectors" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . control_vectors . push_back ({ 1.0f , value , });
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--control-vector-scaled" }, "FNAME" , "SCALE" ,
"add a control vector with user defined scaling SCALE \n "
"note: this argument can be repeated to add multiple scaled control vectors" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & fname , const std :: string & scale ) {
2024-09-09 23:36:09 +02:00
params . control_vectors . push_back ({ std :: stof ( scale ), fname });
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--control-vector-layer-range" }, "START" , "END" ,
"layer range to apply the control vector(s) to, start and end inclusive" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & start , const std :: string & end ) {
2024-09-09 23:36:09 +02:00
params . control_vector_layer_start = std :: stoi ( start );
params . control_vector_layer_end = std :: stoi ( end );
}
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-a" , "--alias" }, "STRING" ,
"set alias for model name (to be used by REST API)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . model_alias = value ;
}
2024-09-25 14:05:13 +02:00
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_ALIAS" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-m" , "--model" }, "FNAME" ,
ex == LLAMA_EXAMPLE_EXPORT_LORA
? std :: string ( "model path from which to load base model" )
2024-10-12 08:21:51 +03:00
: string_format (
2024-09-09 23:36:09 +02:00
"model path (default: `models/$filename` with filename from `--hf-file` "
"or `--model-url` if set, otherwise %s)" , DEFAULT_MODEL_PATH
),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2025-04-01 23:44:05 +02:00
params . model . path = value ;
2024-09-09 23:36:09 +02:00
}
). set_examples ({ LLAMA_EXAMPLE_COMMON , LLAMA_EXAMPLE_EXPORT_LORA }). set_env ( "LLAMA_ARG_MODEL" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-mu" , "--model-url" }, "MODEL_URL" ,
"model download url (default: unused)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2025-04-01 23:44:05 +02:00
params . model . url = value ;
2024-09-09 23:36:09 +02:00
}
). set_env ( "LLAMA_ARG_MODEL_URL" ));
2025-09-12 16:31:50 +01:00
add_opt ( common_arg (
{ "-dr" , "--docker-repo" }, "[<repo>/]<model>[:quant]" ,
"Docker Hub model repository. repo is optional, default to ai/. quant is optional, default to :latest. \n "
"example: gemma3 \n "
"(default: unused)" ,
[]( common_params & params , const std :: string & value ) {
params . model . docker_repo = value ;
}
). set_env ( "LLAMA_ARG_DOCKER_REPO" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2025-01-13 13:56:23 +01:00
{ "-hf" , "-hfr" , "--hf-repo" }, "<user>/<model>[:quant]" ,
"Hugging Face model repository; quant is optional, case-insensitive, default to Q4_K_M, or falls back to the first file in the repo if Q4_K_M doesn't exist. \n "
2025-04-24 12:14:13 +02:00
"mmproj is also downloaded automatically if available. to disable, add --no-mmproj \n "
2025-01-13 13:56:23 +01:00
"example: unsloth/phi-4-GGUF:q4_k_m \n "
"(default: unused)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2025-04-01 23:44:05 +02:00
params . model . hf_repo = value ;
2024-09-09 23:36:09 +02:00
}
). set_env ( "LLAMA_ARG_HF_REPO" ));
2025-01-20 22:29:43 +02:00
add_opt ( common_arg (
{ "-hfd" , "-hfrd" , "--hf-repo-draft" }, "<user>/<model>[:quant]" ,
"Same as --hf-repo, but for the draft model (default: unused)" ,
[]( common_params & params , const std :: string & value ) {
2025-04-01 23:44:05 +02:00
params . speculative . model . hf_repo = value ;
2025-01-20 22:29:43 +02:00
}
). set_env ( "LLAMA_ARG_HFD_REPO" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-hff" , "--hf-file" }, "FILE" ,
2025-01-13 13:56:23 +01:00
"Hugging Face model file. If specified, it will override the quant in --hf-repo (default: unused)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2025-04-01 23:44:05 +02:00
params . model . hf_file = value ;
2024-09-09 23:36:09 +02:00
}
). set_env ( "LLAMA_ARG_HF_FILE" ));
2024-12-18 19:27:21 +02:00
add_opt ( common_arg (
2025-01-13 13:56:23 +01:00
{ "-hfv" , "-hfrv" , "--hf-repo-v" }, "<user>/<model>[:quant]" ,
2024-12-18 19:27:21 +02:00
"Hugging Face model repository for the vocoder model (default: unused)" ,
[]( common_params & params , const std :: string & value ) {
2025-04-01 23:44:05 +02:00
params . vocoder . model . hf_repo = value ;
2024-12-18 19:27:21 +02:00
}
). set_env ( "LLAMA_ARG_HF_REPO_V" ));
add_opt ( common_arg (
{ "-hffv" , "--hf-file-v" }, "FILE" ,
"Hugging Face model file for the vocoder model (default: unused)" ,
[]( common_params & params , const std :: string & value ) {
2025-04-01 23:44:05 +02:00
params . vocoder . model . hf_file = value ;
2024-12-18 19:27:21 +02:00
}
). set_env ( "LLAMA_ARG_HF_FILE_V" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-hft" , "--hf-token" }, "TOKEN" ,
"Hugging Face access token (default: value from HF_TOKEN environment variable)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . hf_token = value ;
}
). set_env ( "HF_TOKEN" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--context-file" }, "FNAME" ,
"file to load context from (repeat to specify multiple files)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
std :: ifstream file ( value , std :: ios :: binary );
if ( ! file ) {
2024-10-12 08:21:51 +03:00
throw std :: runtime_error ( string_format ( "error: failed to open file '%s' \n " , value . c_str ()));
2024-09-09 23:36:09 +02:00
}
params . context_files . push_back ( value );
}
). set_examples ({ LLAMA_EXAMPLE_RETRIEVAL }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--chunk-size" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "minimum length of embedded text chunks (default: %d)" , params . chunk_size ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . chunk_size = value ;
}
). set_examples ({ LLAMA_EXAMPLE_RETRIEVAL }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--chunk-separator" }, "STRING" ,
2024-10-12 08:21:51 +03:00
string_format ( "separator between chunks (default: '%s')" , params . chunk_separator . c_str ()),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . chunk_separator = value ;
}
). set_examples ({ LLAMA_EXAMPLE_RETRIEVAL }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--junk" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "number of times to repeat the junk text (default: %d)" , params . n_junk ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_junk = value ;
}
2025-05-17 12:58:55 +03:00
). set_examples ({ LLAMA_EXAMPLE_PASSKEY , LLAMA_EXAMPLE_PARALLEL }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--pos" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "position of the passkey in the junk text (default: %d)" , params . i_pos ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . i_pos = value ;
}
). set_examples ({ LLAMA_EXAMPLE_PASSKEY }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-o" , "--output" , "--output-file" }, "FNAME" ,
2025-03-10 12:34:13 +01:00
string_format ( "output file (default: '%s')" , params . out_file . c_str ()),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . out_file = value ;
}
2025-08-14 03:03:57 -07:00
). set_examples ({ LLAMA_EXAMPLE_IMATRIX , LLAMA_EXAMPLE_CVECTOR_GENERATOR , LLAMA_EXAMPLE_EXPORT_LORA , LLAMA_EXAMPLE_TTS , LLAMA_EXAMPLE_FINETUNE }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-ofreq" , "--output-frequency" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "output the imatrix every N iterations (default: %d)" , params . n_out_freq ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_out_freq = value ;
}
). set_examples ({ LLAMA_EXAMPLE_IMATRIX }));
2025-08-03 16:00:05 -04:00
add_opt ( common_arg (
{ "--output-format" }, "{gguf,dat}" ,
2025-08-04 17:26:52 -04:00
string_format ( "output format for imatrix file (default: %s)" , params . imat_dat > 0 ? "dat" : "gguf" ),
2025-08-03 16:00:05 -04:00
[]( common_params & params , const std :: string & value ) {
2025-08-04 17:26:52 -04:00
/**/ if ( value == "gguf" ) { params . imat_dat = - 1 ; }
else if ( value == "dat" ) { params . imat_dat = 1 ; }
2025-08-03 16:00:05 -04:00
else { throw std :: invalid_argument ( "invalid output format" ); }
}
). set_examples ({ LLAMA_EXAMPLE_IMATRIX }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--save-frequency" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "save an imatrix copy every N iterations (default: %d)" , params . n_save_freq ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_save_freq = value ;
}
). set_examples ({ LLAMA_EXAMPLE_IMATRIX }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--process-output" },
2024-10-12 08:21:51 +03:00
string_format ( "collect data for the output tensor (default: %s)" , params . process_output ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . process_output = true ;
}
). set_examples ({ LLAMA_EXAMPLE_IMATRIX }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--no-ppl" },
2024-10-12 08:21:51 +03:00
string_format ( "do not compute perplexity (default: %s)" , params . compute_ppl ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . compute_ppl = false ;
}
). set_examples ({ LLAMA_EXAMPLE_IMATRIX }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--chunk" , "--from-chunk" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "start processing the input from chunk N (default: %d)" , params . i_chunk ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . i_chunk = value ;
}
). set_examples ({ LLAMA_EXAMPLE_IMATRIX }));
2025-07-22 13:33:37 +01:00
add_opt ( common_arg (
{ "--show-statistics" },
string_format ( "show imatrix statistics and then exit (default: %s)" , params . show_statistics ? "true" : "false" ),
[]( common_params & params ) {
params . show_statistics = true ;
}
). set_examples ({ LLAMA_EXAMPLE_IMATRIX }));
2025-05-09 05:53:58 -04:00
add_opt ( common_arg (
{ "--parse-special" },
string_format ( "prase special tokens (chat, tool, etc) (default: %s)" , params . parse_special ? "true" : "false" ),
[]( common_params & params ) {
params . parse_special = true ;
}
). set_examples ({ LLAMA_EXAMPLE_IMATRIX }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-pps" },
2024-10-12 08:21:51 +03:00
string_format ( "is the prompt shared across parallel sequences (default: %s)" , params . is_pp_shared ? "true" : "false" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . is_pp_shared = true ;
}
2025-05-17 12:58:55 +03:00
). set_examples ({ LLAMA_EXAMPLE_BENCH , LLAMA_EXAMPLE_PARALLEL }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-npp" }, "n0,n1,..." ,
"number of prompt tokens" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
auto p = string_split < int > ( value , ',' );
params . n_pp . insert ( params . n_pp . end (), p . begin (), p . end ());
}
). set_examples ({ LLAMA_EXAMPLE_BENCH }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-ntg" }, "n0,n1,..." ,
"number of text generation tokens" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
auto p = string_split < int > ( value , ',' );
params . n_tg . insert ( params . n_tg . end (), p . begin (), p . end ());
}
). set_examples ({ LLAMA_EXAMPLE_BENCH }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-npl" }, "n0,n1,..." ,
"number of parallel prompts" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
auto p = string_split < int > ( value , ',' );
params . n_pl . insert ( params . n_pl . end (), p . begin (), p . end ());
}
). set_examples ({ LLAMA_EXAMPLE_BENCH }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--embd-normalize" }, "N" ,
2024-10-22 09:40:02 +02:00
string_format ( "normalisation for embeddings (default: %d) (-1=none, 0=max absolute int16, 1=taxicab, 2=euclidean, >2=p-norm)" , params . embd_normalize ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . embd_normalize = value ;
}
). set_examples ({ LLAMA_EXAMPLE_EMBEDDING }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--embd-output-format" }, "FORMAT" ,
"empty = default, \" array \" = [[],[]...], \" json \" = openai style, \" json+ \" = same \" json \" + cosine similarity matrix" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . embd_out = value ;
}
). set_examples ({ LLAMA_EXAMPLE_EMBEDDING }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--embd-separator" }, "STRING" ,
2024-10-22 09:40:02 +02:00
"separator of embeddings (default \\ n) for example \" <#sep#> \" " ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . embd_sep = value ;
}
). set_examples ({ LLAMA_EXAMPLE_EMBEDDING }));
2025-06-20 14:04:09 +02:00
add_opt ( common_arg (
{ "--cls-separator" }, "STRING" ,
"separator of classification sequences (default \\ t) for example \" <#seq#> \" " ,
[]( common_params & params , const std :: string & value ) {
params . cls_sep = value ;
}
). set_examples ({ LLAMA_EXAMPLE_EMBEDDING }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--host" }, "HOST" ,
2025-03-27 23:41:04 +01:00
string_format ( "ip address to listen, or bind to an UNIX socket if the address ends with .sock (default: %s)" , params . hostname . c_str ()),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . hostname = value ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_HOST" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--port" }, "PORT" ,
2024-10-12 08:21:51 +03:00
string_format ( "port to listen (default: %d)" , params . port ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . port = value ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_PORT" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--path" }, "PATH" ,
2024-10-12 08:21:51 +03:00
string_format ( "path to serve static files from (default: %s)" , params . public_path . c_str ()),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . public_path = value ;
}
2024-09-25 14:05:13 +02:00
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_STATIC_PATH" ));
2025-07-08 11:47:33 +03:00
add_opt ( common_arg (
{ "--api-prefix" }, "PREFIX" ,
string_format ( "prefix path the server serves from, without the trailing slash (default: %s)" , params . api_prefix . c_str ()),
[]( common_params & params , const std :: string & value ) {
params . api_prefix = value ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_API_PREFIX" ));
2024-12-10 17:22:34 +00:00
add_opt ( common_arg (
{ "--no-webui" },
string_format ( "Disable the Web UI (default: %s)" , params . webui ? "enabled" : "disabled" ),
[]( common_params & params ) {
params . webui = false ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_NO_WEBUI" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--embedding" , "--embeddings" },
2024-10-12 08:21:51 +03:00
string_format ( "restrict to only support embedding use case; use only with dedicated embedding models (default: %s)" , params . embedding ? "enabled" : "disabled" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . embedding = true ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_EMBEDDINGS" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-28 17:42:03 +03:00
{ "--reranking" , "--rerank" },
2025-06-16 14:14:00 +03:00
string_format ( "enable reranking endpoint on server (default: %s)" , "disabled" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2025-06-16 14:14:00 +03:00
params . embedding = true ;
params . pooling_type = LLAMA_POOLING_TYPE_RANK ;
2024-09-28 17:42:03 +03:00
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_RERANKING" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--api-key" }, "KEY" ,
"API key to use for authentication (default: none)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . api_keys . push_back ( value );
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_API_KEY" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--api-key-file" }, "FNAME" ,
"path to file containing API keys (default: none)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
std :: ifstream key_file ( value );
if ( ! key_file ) {
2024-10-12 08:21:51 +03:00
throw std :: runtime_error ( string_format ( "error: failed to open file '%s' \n " , value . c_str ()));
2024-09-09 23:36:09 +02:00
}
std :: string key ;
while ( std :: getline ( key_file , key )) {
if ( ! key . empty ()) {
params . api_keys . push_back ( key );
}
}
key_file . close ();
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--ssl-key-file" }, "FNAME" ,
"path to file a PEM-encoded SSL private key" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . ssl_file_key = value ;
}
2024-09-25 14:05:13 +02:00
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_SSL_KEY_FILE" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--ssl-cert-file" }, "FNAME" ,
"path to file a PEM-encoded SSL certificate" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . ssl_file_cert = value ;
}
2024-09-25 14:05:13 +02:00
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_SSL_CERT_FILE" ));
2025-06-29 20:02:53 +02:00
add_opt ( common_arg (
{ "--chat-template-kwargs" }, "STRING" ,
string_format ( "sets additional params for the json template parser" ),
2025-10-12 09:29:13 +03:00
[]( common_params & params , const std :: string & value ) {
2025-06-29 20:02:53 +02:00
auto parsed = json :: parse ( value );
for ( const auto & item : parsed . items ()) {
params . default_template_kwargs [ item . key ()] = item . value (). dump ();
}
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_CHAT_TEMPLATE_KWARGS" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-to" , "--timeout" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "server read/write timeout in seconds (default: %d)" , params . timeout_read ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . timeout_read = value ;
params . timeout_write = value ;
}
2024-09-25 14:05:13 +02:00
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_TIMEOUT" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--threads-http" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "number of threads used to process HTTP requests (default: %d)" , params . n_threads_http ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_threads_http = value ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_THREADS_HTTP" ));
2024-10-13 18:52:48 +03:00
add_opt ( common_arg (
{ "--cache-reuse" }, "N" ,
2025-05-02 09:48:31 +03:00
string_format (
"min chunk size to attempt reusing from the cache via KV shifting (default: %d) \n "
"[(card)](https://ggml.ai/f0.png)" , params . n_cache_reuse
),
2024-10-13 18:52:48 +03:00
[]( common_params & params , int value ) {
params . n_cache_reuse = value ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_CACHE_REUSE" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--metrics" },
2024-10-12 08:21:51 +03:00
string_format ( "enable prometheus compatible metrics endpoint (default: %s)" , params . endpoint_metrics ? "enabled" : "disabled" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . endpoint_metrics = true ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_ENDPOINT_METRICS" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-10-08 13:27:04 +02:00
{ "--props" },
2024-10-12 08:21:51 +03:00
string_format ( "enable changing global properties via POST /props (default: %s)" , params . endpoint_props ? "enabled" : "disabled" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-10-08 13:27:04 +02:00
params . endpoint_props = true ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_ENDPOINT_PROPS" ));
2025-08-31 20:11:58 +03:00
add_opt ( common_arg (
{ "--slots" },
string_format ( "enable slots monitoring endpoint (default: %s)" , params . endpoint_slots ? "enabled" : "disabled" ),
[]( common_params & params ) {
params . endpoint_slots = true ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_ENDPOINT_SLOTS" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--no-slots" },
2024-10-08 13:27:04 +02:00
"disables slots monitoring endpoint" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . endpoint_slots = false ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_NO_ENDPOINT_SLOTS" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--slot-save-path" }, "PATH" ,
"path to save slot kv cache (default: disabled)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . slot_save_path = value ;
// if doesn't end with DIRECTORY_SEPARATOR, add it
if ( ! params . slot_save_path . empty () && params . slot_save_path [ params . slot_save_path . size () - 1 ] != DIRECTORY_SEPARATOR ) {
params . slot_save_path += DIRECTORY_SEPARATOR ;
}
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2025-01-21 13:18:51 +00:00
add_opt ( common_arg (
{ "--jinja" },
"use jinja template for chat (default: disabled)" ,
[]( common_params & params ) {
params . use_jinja = true ;
}
2025-10-23 15:00:49 +02:00
). set_examples ({ LLAMA_EXAMPLE_SERVER , LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_MTMD }). set_env ( "LLAMA_ARG_JINJA" ));
2025-02-13 10:05:16 +00:00
add_opt ( common_arg (
{ "--reasoning-format" }, "FORMAT" ,
2025-05-26 00:30:51 +01:00
"controls whether thought tags are allowed and/or extracted from the response, and in which format they're returned; one of: \n "
"- none: leaves thoughts unparsed in `message.content` \n "
2025-10-08 22:18:41 +02:00
"- deepseek: puts thoughts in `message.reasoning_content` \n "
"- deepseek-legacy: keeps `<think>` tags in `message.content` while also populating `message.reasoning_content` \n "
2025-08-05 22:10:36 +03:00
"(default: auto)" ,
2025-02-13 10:05:16 +00:00
[]( common_params & params , const std :: string & value ) {
2025-08-11 14:48:41 +02:00
params . reasoning_format = common_reasoning_format_from_name ( value );
2025-02-13 10:05:16 +00:00
}
). set_examples ({ LLAMA_EXAMPLE_SERVER , LLAMA_EXAMPLE_MAIN }). set_env ( "LLAMA_ARG_THINK" ));
2025-05-26 00:30:51 +01:00
add_opt ( common_arg (
{ "--reasoning-budget" }, "N" ,
"controls the amount of thinking allowed; currently only one of: -1 for unrestricted thinking budget, or 0 to disable thinking (default: -1)" ,
[]( common_params & params , int value ) {
if ( value != 0 && value != - 1 ) { throw std :: invalid_argument ( "invalid value" ); }
params . reasoning_budget = value ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER , LLAMA_EXAMPLE_MAIN }). set_env ( "LLAMA_ARG_THINK_BUDGET" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--chat-template" }, "JINJA_TEMPLATE" ,
2024-12-02 22:10:19 +01:00
string_format (
"set custom jinja chat template (default: template taken from model's metadata) \n "
"if suffix/prefix are specified, template will be disabled \n "
2025-01-21 13:18:51 +00:00
"only commonly used templates are accepted (unless --jinja is set before this flag): \n "
2024-12-02 22:10:19 +01:00
"list of built-in templates: \n %s" , list_builtin_chat_templates (). c_str ()
),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . chat_template = value ;
}
2025-05-22 20:42:48 +02:00
). set_examples ({ LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_SERVER , LLAMA_EXAMPLE_MTMD }). set_env ( "LLAMA_ARG_CHAT_TEMPLATE" ));
2025-01-21 13:18:51 +00:00
add_opt ( common_arg (
{ "--chat-template-file" }, "JINJA_TEMPLATE_FILE" ,
string_format (
"set custom jinja chat template file (default: template taken from model's metadata) \n "
"if suffix/prefix are specified, template will be disabled \n "
"only commonly used templates are accepted (unless --jinja is set before this flag): \n "
"list of built-in templates: \n %s" , list_builtin_chat_templates (). c_str ()
),
[]( common_params & params , const std :: string & value ) {
2025-04-30 10:46:32 +02:00
params . chat_template = read_file ( value );
2025-01-21 13:18:51 +00:00
}
). set_examples ({ LLAMA_EXAMPLE_MAIN , LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_CHAT_TEMPLATE_FILE" ));
2025-05-17 17:59:48 -04:00
add_opt ( common_arg (
{ "--no-prefill-assistant" },
string_format (
"whether to prefill the assistant's response if the last message is an assistant message (default: prefill enabled) \n "
"when this flag is set, if the last message is an assistant message then it will be treated as a full message and not prefilled \n "
),
[]( common_params & params ) {
params . prefill_assistant = false ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_NO_PREFILL_ASSISTANT" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "-sps" , "--slot-prompt-similarity" }, "SIMILARITY" ,
2024-10-12 08:21:51 +03:00
string_format ( "how much the prompt of a request must match the prompt of a slot in order to use that slot (default: %.2f, 0.0 = disabled) \n " , params . slot_prompt_similarity ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . slot_prompt_similarity = std :: stof ( value );
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--lora-init-without-apply" },
2024-10-12 08:21:51 +03:00
string_format ( "load LoRA adapters without applying them (apply later via POST /lora-adapters) (default: %s)" , params . lora_init_without_apply ? "enabled" : "disabled" ),
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . lora_init_without_apply = true ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--simple-io" },
"use basic IO for better compatibility in subprocesses and limited consoles" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-09 23:36:09 +02:00
params . simple_io = true ;
}
2025-05-07 10:28:02 +03:00
). set_examples ({ LLAMA_EXAMPLE_MAIN }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--positive-file" }, "FNAME" ,
2024-10-12 08:21:51 +03:00
string_format ( "positive prompts file, one prompt per line (default: '%s')" , params . cvector_positive_file . c_str ()),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . cvector_positive_file = value ;
}
). set_examples ({ LLAMA_EXAMPLE_CVECTOR_GENERATOR }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--negative-file" }, "FNAME" ,
2024-10-12 08:21:51 +03:00
string_format ( "negative prompts file, one prompt per line (default: '%s')" , params . cvector_negative_file . c_str ()),
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
params . cvector_negative_file = value ;
}
). set_examples ({ LLAMA_EXAMPLE_CVECTOR_GENERATOR }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--pca-batch" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "batch size used for PCA. Larger batch runs faster, but uses more memory (default: %d)" , params . n_pca_batch ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_pca_batch = value ;
}
). set_examples ({ LLAMA_EXAMPLE_CVECTOR_GENERATOR }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--pca-iter" }, "N" ,
2024-10-12 08:21:51 +03:00
string_format ( "number of iterations used for PCA (default: %d)" , params . n_pca_iterations ),
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-09 23:36:09 +02:00
params . n_pca_iterations = value ;
}
). set_examples ({ LLAMA_EXAMPLE_CVECTOR_GENERATOR }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--method" }, "{pca, mean}" ,
"dimensionality reduction method to be used (default: pca)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
/**/ if ( value == "pca" ) { params . cvector_dimre_method = DIMRE_METHOD_PCA ; }
else if ( value == "mean" ) { params . cvector_dimre_method = DIMRE_METHOD_MEAN ; }
else { throw std :: invalid_argument ( "invalid value" ); }
}
). set_examples ({ LLAMA_EXAMPLE_CVECTOR_GENERATOR }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--output-format" }, "{md,jsonl}" ,
"output format for batched-bench results (default: md)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , const std :: string & value ) {
2024-09-09 23:36:09 +02:00
/**/ if ( value == "jsonl" ) { params . batched_bench_output_jsonl = true ; }
else if ( value == "md" ) { params . batched_bench_output_jsonl = false ; }
2025-05-26 00:30:51 +01:00
else { throw std :: invalid_argument ( "invalid value" ); }
2024-09-09 23:36:09 +02:00
}
). set_examples ({ LLAMA_EXAMPLE_BENCH }));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--log-disable" },
"Log disable" ,
2024-10-10 22:57:42 +02:00
[]( common_params & ) {
common_log_pause ( common_log_main ());
2024-09-15 20:46:12 +03:00
}
2024-09-09 23:36:09 +02:00
));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-09 23:36:09 +02:00
{ "--log-file" }, "FNAME" ,
2024-09-15 20:46:12 +03:00
"Log to file" ,
2024-10-10 22:57:42 +02:00
[]( common_params & , const std :: string & value ) {
common_log_set_file ( common_log_main (), value . c_str ());
2024-09-15 20:46:12 +03:00
}
2024-09-09 23:36:09 +02:00
));
2025-10-12 09:29:13 +03:00
add_opt ( common_arg (
{ "--log-colors" }, "[on|off|auto]" ,
"Set colored logging ('on', 'off', or 'auto', default: 'auto') \n "
"'auto' enables colors when output is to a terminal" ,
[]( common_params & , const std :: string & value ) {
if ( is_truthy ( value )) {
common_log_set_colors ( common_log_main (), LOG_COLORS_ENABLED );
} else if ( is_falsey ( value )) {
common_log_set_colors ( common_log_main (), LOG_COLORS_DISABLED );
} else if ( is_autoy ( value )) {
common_log_set_colors ( common_log_main (), LOG_COLORS_AUTO );
} else {
throw std :: invalid_argument (
string_format ( "error: unkown value for --log-colors: '%s' \n " , value . c_str ()));
}
}
). set_env ( "LLAMA_LOG_COLORS" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-15 20:46:12 +03:00
{ "-v" , "--verbose" , "--log-verbose" },
"Set verbosity level to infinity (i.e. log all messages, useful for debugging)" ,
2024-10-10 22:57:42 +02:00
[]( common_params & params ) {
2024-09-15 20:46:12 +03:00
params . verbosity = INT_MAX ;
2024-10-10 22:57:42 +02:00
common_log_set_verbosity_thold ( INT_MAX );
2024-09-15 20:46:12 +03:00
}
));
2025-05-26 14:34:27 -07:00
add_opt ( common_arg (
{ "--offline" },
"Offline mode: forces use of cache, prevents network access" ,
[]( common_params & params ) {
params . offline = true ;
}
). set_env ( "LLAMA_OFFLINE" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-15 20:46:12 +03:00
{ "-lv" , "--verbosity" , "--log-verbosity" }, "N" ,
"Set the verbosity threshold. Messages with a higher verbosity will be ignored." ,
2024-10-10 22:57:42 +02:00
[]( common_params & params , int value ) {
2024-09-15 20:46:12 +03:00
params . verbosity = value ;
2024-10-10 22:57:42 +02:00
common_log_set_verbosity_thold ( value );
2024-09-15 20:46:12 +03:00
}
). set_env ( "LLAMA_LOG_VERBOSITY" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-15 20:46:12 +03:00
{ "--log-prefix" },
2025-02-16 18:51:13 +09:00
"Enable prefix in log messages" ,
2024-10-10 22:57:42 +02:00
[]( common_params & ) {
common_log_set_prefix ( common_log_main (), true );
2024-09-15 20:46:12 +03:00
}
). set_env ( "LLAMA_LOG_PREFIX" ));
2024-10-10 22:57:42 +02:00
add_opt ( common_arg (
2024-09-15 20:46:12 +03:00
{ "--log-timestamps" },
"Enable timestamps in log messages" ,
2024-10-10 22:57:42 +02:00
[]( common_params & ) {
common_log_set_timestamps ( common_log_main (), true );
2024-09-15 20:46:12 +03:00
}
). set_env ( "LLAMA_LOG_TIMESTAMPS" ));
2024-09-09 23:36:09 +02:00
2024-11-25 09:58:41 +02:00
// speculative parameters
add_opt ( common_arg (
{ "-td" , "--threads-draft" }, "N" ,
"number of threads to use during generation (default: same as --threads)" ,
[]( common_params & params , int value ) {
params . speculative . cpuparams . n_threads = value ;
if ( params . speculative . cpuparams . n_threads <= 0 ) {
params . speculative . cpuparams . n_threads = std :: thread :: hardware_concurrency ();
}
}
2025-08-13 15:43:00 +02:00
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }));
2024-11-25 09:58:41 +02:00
add_opt ( common_arg (
{ "-tbd" , "--threads-batch-draft" }, "N" ,
"number of threads to use during batch and prompt processing (default: same as --threads-draft)" ,
[]( common_params & params , int value ) {
params . speculative . cpuparams_batch . n_threads = value ;
if ( params . speculative . cpuparams_batch . n_threads <= 0 ) {
params . speculative . cpuparams_batch . n_threads = std :: thread :: hardware_concurrency ();
}
}
2025-08-13 15:43:00 +02:00
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }));
2024-11-25 09:58:41 +02:00
add_opt ( common_arg (
{ "-Cd" , "--cpu-mask-draft" }, "M" ,
"Draft model CPU affinity mask. Complements cpu-range-draft (default: same as --cpu-mask)" ,
[]( common_params & params , const std :: string & mask ) {
params . speculative . cpuparams . mask_valid = true ;
if ( ! parse_cpu_mask ( mask , params . speculative . cpuparams . cpumask )) {
throw std :: invalid_argument ( "invalid cpumask" );
}
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }));
add_opt ( common_arg (
{ "-Crd" , "--cpu-range-draft" }, "lo-hi" ,
"Ranges of CPUs for affinity. Complements --cpu-mask-draft" ,
[]( common_params & params , const std :: string & range ) {
params . speculative . cpuparams . mask_valid = true ;
if ( ! parse_cpu_range ( range , params . speculative . cpuparams . cpumask )) {
throw std :: invalid_argument ( "invalid range" );
}
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }));
add_opt ( common_arg (
{ "--cpu-strict-draft" }, "<0|1>" ,
"Use strict CPU placement for draft model (default: same as --cpu-strict)" ,
[]( common_params & params , int value ) {
params . speculative . cpuparams . strict_cpu = value ;
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }));
add_opt ( common_arg (
{ "--prio-draft" }, "N" ,
string_format ( "set draft process/thread priority : 0-normal, 1-medium, 2-high, 3-realtime (default: %d) \n " , params . speculative . cpuparams . priority ),
[]( common_params & params , int prio ) {
if ( prio < 0 || prio > 3 ) {
throw std :: invalid_argument ( "invalid value" );
}
params . speculative . cpuparams . priority = ( enum ggml_sched_priority ) prio ;
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }));
add_opt ( common_arg (
{ "--poll-draft" }, "<0|1>" ,
"Use polling to wait for draft model work (default: same as --poll])" ,
[]( common_params & params , int value ) {
params . speculative . cpuparams . poll = value ;
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }));
add_opt ( common_arg (
{ "-Cbd" , "--cpu-mask-batch-draft" }, "M" ,
"Draft model CPU affinity mask. Complements cpu-range-draft (default: same as --cpu-mask)" ,
[]( common_params & params , const std :: string & mask ) {
params . speculative . cpuparams_batch . mask_valid = true ;
if ( ! parse_cpu_mask ( mask , params . speculative . cpuparams_batch . cpumask )) {
throw std :: invalid_argument ( "invalid cpumask" );
}
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }));
add_opt ( common_arg (
{ "-Crbd" , "--cpu-range-batch-draft" }, "lo-hi" ,
"Ranges of CPUs for affinity. Complements --cpu-mask-draft-batch)" ,
[]( common_params & params , const std :: string & range ) {
params . speculative . cpuparams_batch . mask_valid = true ;
if ( ! parse_cpu_range ( range , params . speculative . cpuparams_batch . cpumask )) {
throw std :: invalid_argument ( "invalid cpumask" );
}
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }));
add_opt ( common_arg (
{ "--cpu-strict-batch-draft" }, "<0|1>" ,
"Use strict CPU placement for draft model (default: --cpu-strict-draft)" ,
[]( common_params & params , int value ) {
params . speculative . cpuparams_batch . strict_cpu = value ;
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }));
add_opt ( common_arg (
{ "--prio-batch-draft" }, "N" ,
string_format ( "set draft process/thread priority : 0-normal, 1-medium, 2-high, 3-realtime (default: %d) \n " , params . speculative . cpuparams_batch . priority ),
[]( common_params & params , int prio ) {
if ( prio < 0 || prio > 3 ) {
throw std :: invalid_argument ( "invalid value" );
}
params . speculative . cpuparams_batch . priority = ( enum ggml_sched_priority ) prio ;
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }));
add_opt ( common_arg (
{ "--poll-batch-draft" }, "<0|1>" ,
"Use polling to wait for draft model work (default: --poll-draft)" ,
[]( common_params & params , int value ) {
params . speculative . cpuparams_batch . poll = value ;
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }));
add_opt ( common_arg (
{ "--draft-max" , "--draft" , "--draft-n" }, "N" ,
string_format ( "number of tokens to draft for speculative decoding (default: %d)" , params . speculative . n_max ),
[]( common_params & params , int value ) {
params . speculative . n_max = value ;
}
2024-12-12 16:57:32 +01:00
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_LOOKUP , LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_DRAFT_MAX" ));
2024-11-25 09:58:41 +02:00
add_opt ( common_arg (
{ "--draft-min" , "--draft-n-min" }, "N" ,
string_format ( "minimum number of draft tokens to use for speculative decoding (default: %d)" , params . speculative . n_min ),
[]( common_params & params , int value ) {
params . speculative . n_min = value ;
}
2024-12-12 16:57:32 +01:00
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_LOOKUP , LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_DRAFT_MIN" ));
2024-11-25 09:58:41 +02:00
add_opt ( common_arg (
{ "--draft-p-split" }, "P" ,
string_format ( "speculative decoding split probability (default: %.1f)" , ( double ) params . speculative . p_split ),
[]( common_params & params , const std :: string & value ) {
params . speculative . p_split = std :: stof ( value );
}
2024-12-12 16:57:32 +01:00
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE }). set_env ( "LLAMA_ARG_DRAFT_P_SPLIT" ));
2024-11-25 09:58:41 +02:00
add_opt ( common_arg (
{ "--draft-p-min" }, "P" ,
string_format ( "minimum speculative decoding probability (greedy) (default: %.1f)" , ( double ) params . speculative . p_min ),
[]( common_params & params , const std :: string & value ) {
params . speculative . p_min = std :: stof ( value );
}
2024-12-12 16:57:32 +01:00
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_DRAFT_P_MIN" ));
2024-11-25 09:58:41 +02:00
add_opt ( common_arg (
{ "-cd" , "--ctx-size-draft" }, "N" ,
string_format ( "size of the prompt context for the draft model (default: %d, 0 = loaded from model)" , params . speculative . n_ctx ),
[]( common_params & params , int value ) {
params . speculative . n_ctx = value ;
}
2024-12-12 16:57:32 +01:00
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_CTX_SIZE_DRAFT" ));
2024-11-25 19:30:06 +01:00
add_opt ( common_arg (
{ "-devd" , "--device-draft" }, "<dev1,dev2,..>" ,
"comma-separated list of devices to use for offloading the draft model (none = don't offload) \n "
"use --list-devices to see a list of available devices" ,
[]( common_params & params , const std :: string & value ) {
params . speculative . devices = parse_device_list ( value );
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }));
2024-11-25 09:58:41 +02:00
add_opt ( common_arg (
{ "-ngld" , "--gpu-layers-draft" , "--n-gpu-layers-draft" }, "N" ,
"number of layers to store in VRAM for the draft model" ,
[]( common_params & params , int value ) {
params . speculative . n_gpu_layers = value ;
if ( ! llama_supports_gpu_offload ()) {
2024-11-28 18:15:25 +01:00
fprintf ( stderr , "warning: no usable GPU found, --gpu-layers-draft option will be ignored \n " );
fprintf ( stderr , "warning: one possible reason is that llama.cpp was compiled without GPU support \n " );
fprintf ( stderr , "warning: consult docs/build.md for compilation instructions \n " );
2024-11-25 09:58:41 +02:00
}
}
2024-12-12 16:57:32 +01:00
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_N_GPU_LAYERS_DRAFT" ));
2024-11-25 09:58:41 +02:00
add_opt ( common_arg (
{ "-md" , "--model-draft" }, "FNAME" ,
"draft model for speculative decoding (default: unused)" ,
[]( common_params & params , const std :: string & value ) {
2025-04-01 23:44:05 +02:00
params . speculative . model . path = value ;
2024-11-25 09:58:41 +02:00
}
2024-12-12 16:57:32 +01:00
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }). set_env ( "LLAMA_ARG_MODEL_DRAFT" ));
2025-07-31 05:25:23 -07:00
add_opt ( common_arg (
{ "--spec-replace" }, "TARGET" , "DRAFT" ,
"translate the string in TARGET into DRAFT if the draft model and main model are not compatible" ,
[]( common_params & params , const std :: string & tgt , const std :: string & dft ) {
params . speculative . replacements . push_back ({ tgt , dft });
}
). set_examples ({ LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER }));
2025-06-19 16:01:03 +03:00
add_opt ( common_arg (
{ "-ctkd" , "--cache-type-k-draft" }, "TYPE" ,
string_format (
"KV cache data type for K for the draft model \n "
"allowed values: %s \n "
"(default: %s)" ,
get_all_kv_cache_types (). c_str (),
ggml_type_name ( params . speculative . cache_type_k )
),
[]( common_params & params , const std :: string & value ) {
params . speculative . cache_type_k = kv_cache_type_from_str ( value );
}
). set_env ( "LLAMA_ARG_CACHE_TYPE_K_DRAFT" ));
add_opt ( common_arg (
{ "-ctvd" , "--cache-type-v-draft" }, "TYPE" ,
string_format (
"KV cache data type for V for the draft model \n "
"allowed values: %s \n "
"(default: %s)" ,
get_all_kv_cache_types (). c_str (),
ggml_type_name ( params . speculative . cache_type_v )
),
[]( common_params & params , const std :: string & value ) {
params . speculative . cache_type_v = kv_cache_type_from_str ( value );
}
). set_env ( "LLAMA_ARG_CACHE_TYPE_V_DRAFT" ));
2024-11-25 09:58:41 +02:00
2024-12-18 19:27:21 +02:00
add_opt ( common_arg (
{ "-mv" , "--model-vocoder" }, "FNAME" ,
"vocoder model for audio generation (default: unused)" ,
[]( common_params & params , const std :: string & value ) {
2025-04-01 23:44:05 +02:00
params . vocoder . model . path = value ;
2024-12-18 19:27:21 +02:00
}
). set_examples ({ LLAMA_EXAMPLE_TTS , LLAMA_EXAMPLE_SERVER }));
2025-01-18 18:20:57 +08:00
add_opt ( common_arg (
{ "--tts-use-guide-tokens" },
"Use guide tokens to improve TTS word recall" ,
[]( common_params & params ) {
params . vocoder . use_guide_tokens = true ;
}
). set_examples ({ LLAMA_EXAMPLE_TTS , LLAMA_EXAMPLE_SERVER }));
2025-03-03 21:09:29 +08:00
add_opt ( common_arg (
{ "--tts-speaker-file" }, "FNAME" ,
"speaker file path for audio generation" ,
[]( common_params & params , const std :: string & value ) {
params . vocoder . speaker_file = value ;
}
). set_examples ({ LLAMA_EXAMPLE_TTS }));
2024-12-18 19:27:21 +02:00
2025-10-12 09:29:13 +03:00
add_opt ( common_arg (
{ "--diffusion-steps" }, "N" ,
string_format ( "number of diffusion steps (default: %d)" , params . diffusion . steps ),
[]( common_params & params , int value ) { params . diffusion . steps = value ; }
). set_examples ({ LLAMA_EXAMPLE_DIFFUSION }));
add_opt ( common_arg (
{ "--diffusion-visual" },
string_format ( "enable visual diffusion mode (show progressive generation) (default: %s)" , params . diffusion . visual_mode ? "true" : "false" ),
[]( common_params & params ) { params . diffusion . visual_mode = true ; }
). set_examples ({ LLAMA_EXAMPLE_DIFFUSION }));
add_opt ( common_arg (
{ "--diffusion-eps" }, "F" ,
string_format ( "epsilon for timesteps (default: %.6f)" , ( double ) params . diffusion . eps ),
[]( common_params & params , const std :: string & value ) { params . diffusion . eps = std :: stof ( value ); }
). set_examples ({ LLAMA_EXAMPLE_DIFFUSION }));
add_opt ( common_arg (
{ "--diffusion-algorithm" }, "N" ,
string_format ( "diffusion algorithm: 0=ORIGIN, 1=ENTROPY_BASED, 2=MARGIN_BASED, 3=RANDOM, 4=LOW_CONFIDENCE (default: %d)" , params . diffusion . algorithm ),
[]( common_params & params , int value ) { params . diffusion . algorithm = value ; }
). set_examples ({ LLAMA_EXAMPLE_DIFFUSION }));
add_opt ( common_arg (
{ "--diffusion-alg-temp" }, "F" ,
string_format ( "dream algorithm temperature (default: %.3f)" , ( double ) params . diffusion . alg_temp ),
[]( common_params & params , const std :: string & value ) { params . diffusion . alg_temp = std :: stof ( value ); }
). set_examples ({ LLAMA_EXAMPLE_DIFFUSION }));
add_opt ( common_arg (
{ "--diffusion-block-length" }, "N" ,
string_format ( "llada block length for generation (default: %d)" , params . diffusion . block_length ),
[]( common_params & params , int value ) { params . diffusion . block_length = value ; }
). set_examples ({ LLAMA_EXAMPLE_DIFFUSION }));
add_opt ( common_arg (
{ "--diffusion-cfg-scale" }, "F" ,
string_format ( "llada classifier-free guidance scale (default: %.3f)" , ( double ) params . diffusion . cfg_scale ),
[]( common_params & params , const std :: string & value ) { params . diffusion . cfg_scale = std :: stof ( value ); }
). set_examples ({ LLAMA_EXAMPLE_DIFFUSION }));
add_opt ( common_arg (
{ "--diffusion-add-gumbel-noise" }, "F" ,
string_format ( "add gumbel noise to the logits if temp > 0.0 (default: %s)" , params . diffusion . add_gumbel_noise ? "true" : "false" ),
[]( common_params & params , const std :: string & value ) { params . diffusion . add_gumbel_noise = std :: stof ( value ); }
). set_examples ({ LLAMA_EXAMPLE_DIFFUSION }));
add_opt ( common_arg (
{ "-lr" , "--learning-rate" }, "ALPHA" ,
string_format ( "adamw or sgd optimizer alpha (default: %.2g); note: sgd alpha recommended ~10x (no momentum)" , ( double ) params . lr . lr0 ),
[]( common_params & params , const std :: string & value ) { params . lr . lr0 = std :: stof ( value ); }
). set_examples ({ LLAMA_EXAMPLE_FINETUNE }));
add_opt ( common_arg ({ "-lr-min" , "--learning-rate-min" }, "ALPHA" ,
string_format ( "(if >0) final learning rate after decay (if -decay-epochs is set, default=%.2g)" ,
( double ) params . lr . lr_min ),
[]( common_params & params , const std :: string & value ) { params . lr . lr_min = std :: stof ( value ); }
). set_examples ({ LLAMA_EXAMPLE_FINETUNE }));
add_opt ( common_arg (
{ "-decay-epochs" , "--learning-rate-decay-epochs" }, "ALPHA" ,
string_format ( "(if >0) decay learning rate to -lr-min after this many epochs (exponential decay, default=%.2g)" , ( double ) params . lr . decay_epochs ),
[]( common_params & params , const std :: string & value ) { params . lr . decay_epochs = std :: stof ( value ); }
). set_examples ({ LLAMA_EXAMPLE_FINETUNE }));
add_opt ( common_arg (
{ "-wd" , "--weight-decay" }, "WD" ,
string_format ( "adamw or sgd optimizer weight decay (0 is off; recommend very small e.g. 1e-9) (default: %.2g)." , ( double ) params . lr . wd ),
[]( common_params & params , const std :: string & value ) { params . lr . wd = std :: stof ( value ); }
). set_examples ({ LLAMA_EXAMPLE_FINETUNE }));
add_opt ( common_arg (
{ "-val-split" , "--val-split" }, "FRACTION" ,
string_format ( "fraction of data to use as validation set for training (default: %.2g)." , ( double ) params . val_split ),
[]( common_params & params , const std :: string & value ) { params . val_split = std :: stof ( value ); }
). set_examples ({ LLAMA_EXAMPLE_FINETUNE }));
add_opt ( common_arg (
{ "-epochs" , "--epochs" }, "N" ,
string_format ( "optimizer max # of epochs (default: %d)" , params . lr . epochs ),
[]( common_params & params , int epochs ) { params . lr . epochs = epochs ; }
). set_examples ({ LLAMA_EXAMPLE_FINETUNE }));
add_opt ( common_arg (
{ "-opt" , "--optimizer" }, "sgd|adamw" , "adamw or sgd" ,
[]( common_params & params , const std :: string & name ) {
params . optimizer = common_opt_get_optimizer ( name . c_str ());
if ( params . optimizer == GGML_OPT_OPTIMIZER_TYPE_COUNT ) {
throw std :: invalid_argument ( "invalid --optimizer, valid options: adamw, sgd" );
}
}
). set_examples ({ LLAMA_EXAMPLE_FINETUNE }));
// presets
2024-12-19 17:35:15 +02:00
add_opt ( common_arg (
{ "--tts-oute-default" },
string_format ( "use default OuteTTS models (note: can download weights from the internet)" ),
[]( common_params & params ) {
2025-04-01 23:44:05 +02:00
params . model . hf_repo = "OuteAI/OuteTTS-0.2-500M-GGUF" ;
params . model . hf_file = "OuteTTS-0.2-500M-Q8_0.gguf" ;
params . vocoder . model . hf_repo = "ggml-org/WavTokenizer" ;
params . vocoder . model . hf_file = "WavTokenizer-Large-75-F16.gguf" ;
2024-12-19 17:35:15 +02:00
}
). set_examples ({ LLAMA_EXAMPLE_TTS }));
2025-02-07 09:15:22 +01:00
add_opt ( common_arg (
2025-10-12 09:29:13 +03:00
{ "--embd-gemma-default" },
string_format ( "use default EmbeddingGemma model (note: can download weights from the internet)" ),
2025-02-07 09:15:22 +01:00
[]( common_params & params ) {
2025-10-12 09:29:13 +03:00
params . model . hf_repo = "ggml-org/embeddinggemma-300M-qat-q4_0-GGUF" ;
params . model . hf_file = "embeddinggemma-300M-qat-Q4_0.gguf" ;
params . port = 8011 ;
params . n_ubatch = 2048 ;
params . n_batch = 2048 ;
params . n_parallel = 32 ;
params . n_ctx = 2048 * params . n_parallel ;
2025-02-07 09:15:22 +01:00
params . verbose_prompt = true ;
params . embedding = true ;
}
). set_examples ({ LLAMA_EXAMPLE_EMBEDDING , LLAMA_EXAMPLE_SERVER }));
2025-02-19 12:29:52 +01:00
add_opt ( common_arg (
{ "--fim-qwen-1.5b-default" },
string_format ( "use default Qwen 2.5 Coder 1.5B (note: can download weights from the internet)" ),
[]( common_params & params ) {
2025-04-01 23:44:05 +02:00
params . model . hf_repo = "ggml-org/Qwen2.5-Coder-1.5B-Q8_0-GGUF" ;
params . model . hf_file = "qwen2.5-coder-1.5b-q8_0.gguf" ;
2025-02-19 12:29:52 +01:00
params . port = 8012 ;
params . n_ubatch = 1024 ;
params . n_batch = 1024 ;
params . n_ctx = 0 ;
params . n_cache_reuse = 256 ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
add_opt ( common_arg (
{ "--fim-qwen-3b-default" },
string_format ( "use default Qwen 2.5 Coder 3B (note: can download weights from the internet)" ),
[]( common_params & params ) {
2025-04-01 23:44:05 +02:00
params . model . hf_repo = "ggml-org/Qwen2.5-Coder-3B-Q8_0-GGUF" ;
params . model . hf_file = "qwen2.5-coder-3b-q8_0.gguf" ;
2025-02-19 12:29:52 +01:00
params . port = 8012 ;
params . n_ubatch = 1024 ;
params . n_batch = 1024 ;
params . n_ctx = 0 ;
params . n_cache_reuse = 256 ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
add_opt ( common_arg (
{ "--fim-qwen-7b-default" },
string_format ( "use default Qwen 2.5 Coder 7B (note: can download weights from the internet)" ),
[]( common_params & params ) {
2025-04-01 23:44:05 +02:00
params . model . hf_repo = "ggml-org/Qwen2.5-Coder-7B-Q8_0-GGUF" ;
params . model . hf_file = "qwen2.5-coder-7b-q8_0.gguf" ;
2025-02-19 12:29:52 +01:00
params . port = 8012 ;
params . n_ubatch = 1024 ;
params . n_batch = 1024 ;
params . n_ctx = 0 ;
params . n_cache_reuse = 256 ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2025-03-09 19:08:20 +02:00
add_opt ( common_arg (
{ "--fim-qwen-7b-spec" },
string_format ( "use Qwen 2.5 Coder 7B + 0.5B draft for speculative decoding (note: can download weights from the internet)" ),
[]( common_params & params ) {
2025-04-01 23:44:05 +02:00
params . model . hf_repo = "ggml-org/Qwen2.5-Coder-7B-Q8_0-GGUF" ;
params . model . hf_file = "qwen2.5-coder-7b-q8_0.gguf" ;
params . speculative . model . hf_repo = "ggml-org/Qwen2.5-Coder-0.5B-Q8_0-GGUF" ;
params . speculative . model . hf_file = "qwen2.5-coder-0.5b-q8_0.gguf" ;
2025-03-09 19:08:20 +02:00
params . port = 8012 ;
params . n_ubatch = 1024 ;
params . n_batch = 1024 ;
params . n_ctx = 0 ;
params . n_cache_reuse = 256 ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
add_opt ( common_arg (
{ "--fim-qwen-14b-spec" },
string_format ( "use Qwen 2.5 Coder 14B + 0.5B draft for speculative decoding (note: can download weights from the internet)" ),
[]( common_params & params ) {
2025-04-01 23:44:05 +02:00
params . model . hf_repo = "ggml-org/Qwen2.5-Coder-14B-Q8_0-GGUF" ;
params . model . hf_file = "qwen2.5-coder-14b-q8_0.gguf" ;
params . speculative . model . hf_repo = "ggml-org/Qwen2.5-Coder-0.5B-Q8_0-GGUF" ;
params . speculative . model . hf_file = "qwen2.5-coder-0.5b-q8_0.gguf" ;
2025-03-09 19:08:20 +02:00
params . port = 8012 ;
params . n_ubatch = 1024 ;
params . n_batch = 1024 ;
params . n_ctx = 0 ;
params . n_cache_reuse = 256 ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2025-08-27 15:48:07 +03:00
add_opt ( common_arg (
{ "--fim-qwen-30b-default" },
string_format ( "use default Qwen 3 Coder 30B A3B Instruct (note: can download weights from the internet)" ),
[]( common_params & params ) {
params . model . hf_repo = "ggml-org/Qwen3-Coder-30B-A3B-Instruct-Q8_0-GGUF" ;
params . model . hf_file = "qwen3-coder-30b-a3b-instruct-q8_0.gguf" ;
params . port = 8012 ;
params . n_ubatch = 1024 ;
params . n_batch = 1024 ;
params . n_ctx = 0 ;
params . n_cache_reuse = 256 ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2025-07-16 20:03:51 +08:00
add_opt ( common_arg (
2025-10-12 09:29:13 +03:00
{ "--gpt-oss-20b-default" },
string_format ( "use gpt-oss-20b (note: can download weights from the internet)" ),
[]( common_params & params ) {
params . model . hf_repo = "ggml-org/gpt-oss-20b-GGUF" ;
params . model . hf_file = "gpt-oss-20b-mxfp4.gguf" ;
params . port = 8013 ;
params . n_ubatch = 2048 ;
params . n_batch = 32768 ;
params . n_parallel = 2 ;
params . n_ctx = 131072 * params . n_parallel ;
params . sampling . temp = 1.0f ;
params . sampling . top_p = 1.0f ;
params . sampling . top_k = 0 ;
params . sampling . min_p = 0.01f ;
params . use_jinja = true ;
//params.default_template_kwargs["reasoning_effort"] = "\"high\"";
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2025-07-16 20:03:51 +08:00
2025-07-31 19:49:09 +08:00
add_opt ( common_arg (
2025-10-12 09:29:13 +03:00
{ "--gpt-oss-120b-default" },
string_format ( "use gpt-oss-120b (note: can download weights from the internet)" ),
[]( common_params & params ) {
params . model . hf_repo = "ggml-org/gpt-oss-120b-GGUF" ;
params . port = 8013 ;
params . n_ubatch = 2048 ;
params . n_batch = 32768 ;
params . n_parallel = 2 ;
params . n_ctx = 131072 * params . n_parallel ;
params . sampling . temp = 1.0f ;
params . sampling . top_p = 1.0f ;
params . sampling . top_k = 0 ;
params . sampling . min_p = 0.01f ;
params . use_jinja = true ;
//params.default_template_kwargs["reasoning_effort"] = "\"high\"";
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2025-07-31 19:49:09 +08:00
add_opt ( common_arg (
2025-10-12 09:29:13 +03:00
{ "--vision-gemma-4b-default" },
string_format ( "use Gemma 3 4B QAT (note: can download weights from the internet)" ),
[]( common_params & params ) {
params . model . hf_repo = "ggml-org/gemma-3-4b-it-qat-GGUF" ;
params . port = 8014 ;
params . n_ctx = 0 ;
params . use_jinja = true ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2025-07-31 19:49:09 +08:00
2025-08-14 03:03:57 -07:00
add_opt ( common_arg (
2025-10-12 09:29:13 +03:00
{ "--vision-gemma-12b-default" },
string_format ( "use Gemma 3 12B QAT (note: can download weights from the internet)" ),
[]( common_params & params ) {
params . model . hf_repo = "ggml-org/gemma-3-12b-it-qat-GGUF" ;
params . port = 8014 ;
params . n_ctx = 0 ;
params . use_jinja = true ;
}
). set_examples ({ LLAMA_EXAMPLE_SERVER }));
2025-08-14 03:03:57 -07:00
2024-09-09 23:36:09 +02:00
return ctx_arg ;
}