← Back to C-Kernel-Engine Docs Doxygen Source Documentation
v6_cli.c
Go to the documentation of this file.
1 /**
2  * @file v6_cli.c
3  * @brief C-Kernel-Engine v6 CLI
4  *
5  * Usage:
6  * ./ck-engine-v6 -m <model.gguf> [options]
7  * ./ck-engine-v6 -m <model.gguf> -p "Hello world"
8  * ./ck-engine-v6 -m <model.gguf> -p @prompt.txt --temp 0.7
9  *
10  * Options:
11  * -m, --model <file> Model file (GGUF or BUMP)
12  * -p, --prompt <text> Prompt (use @file.txt to read from file)
13  * -t, --tokens <n> Max tokens to generate (default: 100)
14  * -t, --temp <float> Temperature (default: 0.7)
15  * -p, --top-p <float> Top-p sampling (default: 0.9)
16  * -k, --top-k <n> Top-k sampling (default: 40)
17  * --seed <n> Random seed (default: random)
18  * --threads <n> Number of threads (default: auto)
19  * --no-kv-cache Disable KV cache
20  * --ignore-eos Ignore EOS token
21  * --verbose Verbose output
22  * -v, --version Show version
23  * -h, --help Show this help
24  */
25 
26 #define _GNU_SOURCE
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdint.h>
30 #include <string.h>
31 #include <time.h>
32 #include <math.h>
33 #include <limits.h>
34 #include <unistd.h>
35 
36 #include "ckernel_engine.h"
37 
38 /* Version */
39 #define CK_VERSION "6.0.0"
40 #define CK_BUILD_DATE __DATE__
41 
42 /* ANSI colors */
43 #define ANSI_RESET "\033[0m"
44 #define ANSI_BOLD "\033[1m"
45 #define ANSI_DIM "\033[2m"
46 #define ANSI_GREEN "\033[0;32m"
47 #define ANSI_YELLOW "\033[0;33m"
48 #define ANSI_BLUE "\033[0;34m"
49 #define ANSI_CYAN "\033[0;36m"
50 
51 /* Model configuration (defaults) */
52 typedef struct {
53  const char *model_path;
54  const char *prompt;
55  int max_tokens;
56  float temperature;
57  float top_p;
58  int top_k;
59  int seed;
60  int threads;
61  int kv_cache;
62  int ignore_eos;
63  int verbose;
64 } CLIArgs;
65 
66 /* Print banner */
67 static void print_banner(void) {
68  printf(ANSI_CYAN);
69  printf("\n");
70  printf(" C-Kernel-Engine\n");
71  printf(" ------------------------------\n");
72  printf(ANSI_RESET);
73  printf(ANSI_DIM);
74  printf(" v%s - %s - Native C Implementation\n", CK_VERSION, CK_BUILD_DATE);
75  printf(" " ANSI_GREEN "https://github.com/antshiv/C-Kernel-Engine" ANSI_RESET "\n");
76  printf("\n");
77 }
78 
79 /* Print help */
80 static void print_help(const char *prog) {
81  printf(ANSI_BOLD "usage:" ANSI_RESET " %s [options]\n\n", prog);
82  printf(ANSI_BOLD "options:" ANSI_RESET "\n");
83  printf(" -m, --model <file> Model file (GGUF or BUMP)\n");
84  printf(" -p, --prompt <text> Prompt (use @file.txt to read from file)\n");
85  printf(" -t, --tokens <n> Max tokens to generate (default: 100)\n");
86  printf(" -t, --temp <float> Temperature (default: 0.7)\n");
87  printf(" --top-p <float> Top-p sampling (default: 0.9)\n");
88  printf(" --top-k <n> Top-k sampling (default: 40)\n");
89  printf(" --seed <n> Random seed (default: random)\n");
90  printf(" --threads <n> Number of threads (default: auto)\n");
91  printf(" --no-kv-cache Disable KV cache\n");
92  printf(" --ignore-eos Ignore EOS token\n");
93  printf(" --verbose Verbose output\n");
94  printf(" -v, --version Show version\n");
95  printf(" -h, --help Show this help\n");
96  printf("\n");
97  printf(ANSI_BOLD "examples:" ANSI_RESET "\n");
98  printf(" %s -m model.gguf -p \"Hello\"\n", prog);
99  printf(" %s -m model.gguf -p @prompt.txt -t 50 --temp 0.8\n", prog);
100  printf(" %s -m model.gguf --seed 42 --verbose\n", prog);
101  printf("\n");
102 }
103 
104 /* Print version */
105 static void print_version(void) {
106  printf(ANSI_BOLD "C-Kernel-Engine" ANSI_RESET " v" CK_VERSION "\n");
107  printf("Build: " CK_BUILD_DATE "\n");
108  printf("C标准: " ANSI_YELLOW "C11" ANSI_RESET "\n");
109  printf("OMP支持: " ANSI_YELLOW "Yes" ANSI_RESET "\n");
110 }
111 
112 /* Parse arguments */
113 static CLIArgs parse_args(int argc, char **argv) {
114  CLIArgs args = {
115  .model_path = NULL,
116  .prompt = "Hello",
117  .max_tokens = 100,
118  .temperature = 0.7f,
119  .top_p = 0.9f,
120  .top_k = 40,
121  .seed = -1,
122  .threads = 0,
123  .kv_cache = 1,
124  .ignore_eos = 0,
125  .verbose = 0,
126  };
127 
128  for (int i = 1; i < argc; i++) {
129  if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
130  print_banner();
131  print_help(argv[0]);
132  exit(0);
133  }
134  if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
135  print_version();
136  exit(0);
137  }
138  if ((strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--model") == 0) && i + 1 < argc) {
139  args.model_path = argv[++i];
140  }
141  else if ((strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--prompt") == 0) && i + 1 < argc) {
142  args.prompt = argv[++i];
143  }
144  else if ((strcmp(argv[i], "-t") == 0) && i + 1 < argc) {
145  args.max_tokens = atoi(argv[++i]);
146  }
147  else if (strcmp(argv[i], "--temp") == 0 && i + 1 < argc) {
148  args.temperature = atof(argv[++i]);
149  }
150  else if (strcmp(argv[i], "--top-p") == 0 && i + 1 < argc) {
151  args.top_p = atof(argv[++i]);
152  }
153  else if (strcmp(argv[i], "--top-k") == 0 && i + 1 < argc) {
154  args.top_k = atoi(argv[++i]);
155  }
156  else if (strcmp(argv[i], "--seed") == 0 && i + 1 < argc) {
157  args.seed = atoi(argv[++i]);
158  }
159  else if (strcmp(argv[i], "--threads") == 0 && i + 1 < argc) {
160  args.threads = atoi(argv[++i]);
161  }
162  else if (strcmp(argv[i], "--no-kv-cache") == 0) {
163  args.kv_cache = 0;
164  }
165  else if (strcmp(argv[i], "--ignore-eos") == 0) {
166  args.ignore_eos = 1;
167  }
168  else if (strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
169  args.verbose = 1;
170  }
171  else {
172  fprintf(stderr, "Unknown option: %s\n", argv[i]);
173  fprintf(stderr, "Use --help for usage\n");
174  exit(1);
175  }
176  }
177 
178  return args;
179 }
180 
181 /* Read prompt from file */
182 static char *read_prompt_file(const char *path) {
183  if (path[0] != '@') return (char *)path;
184 
185  FILE *f = fopen(path + 1, "r");
186  if (!f) {
187  fprintf(stderr, "Cannot open prompt file: %s\n", path + 1);
188  return (char *)path;
189  }
190 
191  char *content = malloc(4096);
192  size_t len = fread(content, 1, 4095, f);
193  content[len] = '\0';
194  fclose(f);
195 
196  // Remove trailing newlines
197  while (len > 0 && (content[len-1] == '\n' || content[len-1] == '\r')) {
198  content[--len] = '\0';
199  }
200 
201  return content;
202 }
203 
204 /* Simple tokenization (placeholder) */
205 static int32_t *tokenize(const char *text, int *num_tokens) {
206  static int32_t tokens[1024];
207  *num_tokens = strlen(text);
208  for (int i = 0; i < *num_tokens && i < 1024; i++) {
209  tokens[i] = (int32_t)text[i];
210  }
211  return tokens;
212 }
213 
214 /* Sample from logits (simplified) */
215 static int sample_token(float *logits, int vocab_size, float temp, int top_k) {
216  float max_val = logits[0];
217  for (int i = 1; i < vocab_size; i++) {
218  if (logits[i] > max_val) max_val = logits[i];
219  }
220 
221  float sum = 0.0f;
222  for (int i = 0; i < vocab_size; i++) {
223  logits[i] = expf((logits[i] - max_val) / temp);
224  sum += logits[i];
225  }
226 
227  // Top-k filter
228  int start = vocab_size > top_k ? vocab_size - top_k : 0;
229 
230  // Simple argmax
231  float best_val = logits[start];
232  int best_idx = start;
233  for (int i = start + 1; i < vocab_size; i++) {
234  if (logits[i] > best_val) {
235  best_val = logits[i];
236  best_idx = i;
237  }
238  }
239 
240  return best_idx;
241 }
242 
243 /* Print progress */
244 static void print_progress(int token_id, float token_per_sec) {
245  static time_t last_time = 0;
246  time_t now = time(NULL);
247 
248  if (now - last_time >= 1) {
249  printf(ANSI_DIM "[ %.1f tok/s ]" ANSI_RESET "\r", token_per_sec);
250  fflush(stdout);
251  last_time = now;
252  }
253 }
254 
255 int main(int argc, char **argv) {
256  CLIArgs args = parse_args(argc, argv);
257 
258  /* Print banner */
259  if (!args.verbose) {
260  print_banner();
261  }
262 
263  /* Validate arguments */
264  if (!args.model_path) {
265  fprintf(stderr, ANSI_YELLOW "Error:" ANSI_RESET " No model specified\n");
266  fprintf(stderr, "Use " ANSI_BOLD "-m <model>" ANSI_RESET " or " ANSI_BOLD "--help" ANSI_RESET "\n");
267  return 1;
268  }
269 
270  /* Check if model file exists */
271  if (access(args.model_path, F_OK) != 0) {
272  fprintf(stderr, ANSI_YELLOW "Error:" ANSI_RESET " Model file not found: %s\n", args.model_path);
273  return 1;
274  }
275 
276  /* Read prompt */
277  char *prompt = read_prompt_file(args.prompt);
278 
279  /* Set random seed */
280  if (args.seed < 0) {
281  args.seed = (int)time(NULL);
282  }
283  srand(args.seed);
284 
285  /* Print inference parameters */
286  printf(ANSI_BOLD "Parameters:" ANSI_RESET "\n");
287  printf(" Model: " ANSI_CYAN "%s" ANSI_RESET "\n", args.model_path);
288  printf(" Prompt: \"" ANSI_YELLOW "%s" ANSI_RESET "\"\n", prompt);
289  printf(" Tokens: %d\n", args.max_tokens);
290  printf(" Temp: %.2f\n", args.temperature);
291  printf(" Top-p: %.2f\n", args.top_p);
292  printf(" Top-k: %d\n", args.top_k);
293  printf(" Seed: %d\n", args.seed);
294  printf(" Threads: %d\n", args.threads > 0 ? args.threads : 4);
295  printf("\n");
296 
297  /* Start generation */
298  printf(ANSI_BOLD "Output:" ANSI_RESET "\n");
299  printf(ANSI_YELLOW);
300  fflush(stdout);
301 
302  /* Placeholder inference - in real impl would load model and run */
303  printf("<Model loading would happen here>\n");
304  printf("<Inference would run here>\n");
305  printf("\n");
306 
307  /* Demo output */
308  printf(ANSI_RESET);
309  printf(ANSI_BOLD "Note:" ANSI_RESET " This is v6 placeholder CLI.\n");
310  printf("Full model loading and inference requires:\n");
311  printf(" 1. Generated model code from IR\n");
312  printf(" 2. All kernel implementations compiled\n");
313  printf(" 3. Weight loading from GGUF/BUMP\n");
314  printf("\n");
315 
316  /* Cleanup */
317  if (prompt != args.prompt) {
318  free(prompt);
319  }
320 
321  return 0;
322 }
const char * text
Definition: tokenizer.h:563
int vocab_size
Definition: true_bpe.h:185
uint32_t start
Definition: utf8.c:214
static int32_t * tokenize(const char *text, int *num_tokens)
Definition: v6_cli.c:205
static void print_progress(int token_id, float token_per_sec)
Definition: v6_cli.c:244
static int sample_token(float *logits, int vocab_size, float temp, int top_k)
Definition: v6_cli.c:215
static void print_version(void)
Definition: v6_cli.c:105
int main(int argc, char **argv)
Definition: v6_cli.c:255
static void print_help(const char *prog)
Definition: v6_cli.c:80
#define ANSI_BOLD
Definition: v6_cli.c:44
#define CK_BUILD_DATE
Definition: v6_cli.c:40
#define ANSI_DIM
Definition: v6_cli.c:45
static CLIArgs parse_args(int argc, char **argv)
Definition: v6_cli.c:113
#define ANSI_CYAN
Definition: v6_cli.c:49
static void print_banner(void)
Definition: v6_cli.c:67
static char * read_prompt_file(const char *path)
Definition: v6_cli.c:182
#define CK_VERSION
Definition: v6_cli.c:39
#define ANSI_GREEN
Definition: v6_cli.c:46
#define ANSI_YELLOW
Definition: v6_cli.c:47
#define ANSI_RESET
Definition: v6_cli.c:43