18
18
#include < signal.h>
19
19
#endif
20
20
21
- #if defined (_WIN32)
22
- #pragma comment(lib,"kernel32.lib")
23
- extern " C" __declspec(dllimport) void * __stdcall GetStdHandle (unsigned long nStdHandle);
24
- extern " C" __declspec(dllimport) int __stdcall GetConsoleMode (void * hConsoleHandle, unsigned long * lpMode);
25
- extern " C" __declspec(dllimport) int __stdcall SetConsoleMode (void * hConsoleHandle, unsigned long dwMode);
26
- extern " C" __declspec(dllimport) int __stdcall SetConsoleCP (unsigned int wCodePageID);
27
- extern " C" __declspec(dllimport) int __stdcall SetConsoleOutputCP (unsigned int wCodePageID);
28
- #endif
29
-
30
- #define ANSI_COLOR_RED " \x1b [31m"
31
- #define ANSI_COLOR_GREEN " \x1b [32m"
32
- #define ANSI_COLOR_YELLOW " \x1b [33m"
33
- #define ANSI_COLOR_BLUE " \x1b [34m"
34
- #define ANSI_COLOR_MAGENTA " \x1b [35m"
35
- #define ANSI_COLOR_CYAN " \x1b [36m"
36
- #define ANSI_COLOR_RESET " \x1b [0m"
37
- #define ANSI_BOLD " \x1b [1m"
38
-
39
- /* Keep track of current color of output, and emit ANSI code if it changes. */
40
- enum console_state {
41
- CONSOLE_STATE_DEFAULT=0 ,
42
- CONSOLE_STATE_PROMPT,
43
- CONSOLE_STATE_USER_INPUT
44
- };
45
-
46
- static console_state con_st = CONSOLE_STATE_DEFAULT;
47
- static bool con_use_color = false ;
48
-
49
- void set_console_state (console_state new_st) {
50
- if (!con_use_color) return ;
51
- // only emit color code if state changed
52
- if (new_st != con_st) {
53
- con_st = new_st;
54
- switch (con_st) {
55
- case CONSOLE_STATE_DEFAULT:
56
- printf (ANSI_COLOR_RESET);
57
- return ;
58
- case CONSOLE_STATE_PROMPT:
59
- printf (ANSI_COLOR_YELLOW);
60
- return ;
61
- case CONSOLE_STATE_USER_INPUT:
62
- printf (ANSI_BOLD ANSI_COLOR_GREEN);
63
- return ;
64
- }
65
- }
66
- }
21
+ static console_state con_st;
67
22
68
23
static bool is_interacting = false ;
69
24
70
25
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) || defined (_WIN32)
71
26
void sigint_handler (int signo) {
72
- set_console_state (CONSOLE_STATE_DEFAULT );
27
+ set_console_color (con_st, CONSOLE_COLOR_DEFAULT );
73
28
printf (" \n " ); // this also force flush stdout.
74
29
if (signo == SIGINT) {
75
30
if (!is_interacting) {
@@ -81,32 +36,6 @@ void sigint_handler(int signo) {
81
36
}
82
37
#endif
83
38
84
- #if defined (_WIN32)
85
- void win32_console_init (void ) {
86
- unsigned long dwMode = 0 ;
87
- void * hConOut = GetStdHandle ((unsigned long )-11 ); // STD_OUTPUT_HANDLE (-11)
88
- if (!hConOut || hConOut == (void *)-1 || !GetConsoleMode (hConOut, &dwMode)) {
89
- hConOut = GetStdHandle ((unsigned long )-12 ); // STD_ERROR_HANDLE (-12)
90
- if (hConOut && (hConOut == (void *)-1 || !GetConsoleMode (hConOut, &dwMode))) {
91
- hConOut = 0 ;
92
- }
93
- }
94
- if (hConOut) {
95
- // Enable ANSI colors on Windows 10+
96
- if (con_use_color && !(dwMode & 0x4 )) {
97
- SetConsoleMode (hConOut, dwMode | 0x4 ); // ENABLE_VIRTUAL_TERMINAL_PROCESSING (0x4)
98
- }
99
- // Set console output codepage to UTF8
100
- SetConsoleOutputCP (65001 ); // CP_UTF8
101
- }
102
- void * hConIn = GetStdHandle ((unsigned long )-10 ); // STD_INPUT_HANDLE (-10)
103
- if (hConIn && hConIn != (void *)-1 && GetConsoleMode (hConIn, &dwMode)) {
104
- // Set console input codepage to UTF8
105
- SetConsoleCP (65001 ); // CP_UTF8
106
- }
107
- }
108
- #endif
109
-
110
39
int main (int argc, char ** argv) {
111
40
gpt_params params;
112
41
params.model = " models/llama-7B/ggml-model.bin" ;
@@ -115,13 +44,12 @@ int main(int argc, char ** argv) {
115
44
return 1 ;
116
45
}
117
46
118
-
119
47
// save choice to use color for later
120
48
// (note for later: this is a slightly awkward choice)
121
- con_use_color = params.use_color ;
49
+ con_st. use_color = params.use_color ;
122
50
123
51
#if defined (_WIN32)
124
- win32_console_init ();
52
+ win32_console_init (params. use_color );
125
53
#endif
126
54
127
55
if (params.perplexity ) {
@@ -218,24 +146,23 @@ int main(int argc, char ** argv) {
218
146
return 1 ;
219
147
}
220
148
221
- params.n_keep = std::min (params.n_keep , (int ) embd_inp.size ());
149
+ // number of tokens to keep when resetting context
150
+ if (params.n_keep < 0 || params.n_keep > (int )embd_inp.size () || params.instruct ) {
151
+ params.n_keep = (int )embd_inp.size ();
152
+ }
222
153
223
154
// prefix & suffix for instruct mode
224
155
const auto inp_pfx = ::llama_tokenize (ctx, " \n\n ### Instruction:\n\n " , true );
225
156
const auto inp_sfx = ::llama_tokenize (ctx, " \n\n ### Response:\n\n " , false );
226
157
227
158
// in instruct mode, we inject a prefix and a suffix to each input by the user
228
159
if (params.instruct ) {
229
- params.interactive = true ;
160
+ params.interactive_start = true ;
230
161
params.antiprompt .push_back (" ### Instruction:\n\n " );
231
162
}
232
163
233
- // enable interactive mode if reverse prompt is specified
234
- if (params.antiprompt .size () != 0 ) {
235
- params.interactive = true ;
236
- }
237
-
238
- if (params.interactive_start ) {
164
+ // enable interactive mode if reverse prompt or interactive start is specified
165
+ if (params.antiprompt .size () != 0 || params.interactive_start ) {
239
166
params.interactive = true ;
240
167
}
241
168
@@ -297,17 +224,18 @@ int main(int argc, char ** argv) {
297
224
#endif
298
225
" - Press Return to return control to LLaMa.\n "
299
226
" - If you want to submit another line, end your input in '\\ '.\n\n " );
300
- is_interacting = params.interactive_start || params. instruct ;
227
+ is_interacting = params.interactive_start ;
301
228
}
302
229
303
- bool input_noecho = false ;
230
+ bool is_antiprompt = false ;
231
+ bool input_noecho = false ;
304
232
305
233
int n_past = 0 ;
306
234
int n_remain = params.n_predict ;
307
235
int n_consumed = 0 ;
308
236
309
237
// the first thing we will do is to output the prompt, so set color accordingly
310
- set_console_state (CONSOLE_STATE_PROMPT );
238
+ set_console_color (con_st, CONSOLE_COLOR_PROMPT );
311
239
312
240
std::vector<llama_token> embd;
313
241
@@ -408,36 +336,38 @@ int main(int argc, char ** argv) {
408
336
}
409
337
// reset color to default if we there is no pending user input
410
338
if (!input_noecho && (int )embd_inp.size () == n_consumed) {
411
- set_console_state (CONSOLE_STATE_DEFAULT );
339
+ set_console_color (con_st, CONSOLE_COLOR_DEFAULT );
412
340
}
413
341
414
342
// in interactive mode, and not currently processing queued inputs;
415
343
// check if we should prompt the user for more
416
344
if (params.interactive && (int ) embd_inp.size () <= n_consumed) {
345
+
417
346
// check for reverse prompt
418
- std::string last_output;
419
- for (auto id : last_n_tokens) {
420
- last_output += llama_token_to_str (ctx, id);
421
- }
347
+ if (params.antiprompt .size ()) {
348
+ std::string last_output;
349
+ for (auto id : last_n_tokens) {
350
+ last_output += llama_token_to_str (ctx, id);
351
+ }
422
352
423
- // Check if each of the reverse prompts appears at the end of the output.
424
- for (std::string & antiprompt : params.antiprompt ) {
425
- if (last_output.find (antiprompt.c_str (), last_output.length () - antiprompt.length (), antiprompt.length ()) != std::string::npos) {
426
- is_interacting = true ;
427
- set_console_state (CONSOLE_STATE_USER_INPUT);
428
- fflush (stdout);
429
- break ;
353
+ is_antiprompt = false ;
354
+ // Check if each of the reverse prompts appears at the end of the output.
355
+ for (std::string & antiprompt : params.antiprompt ) {
356
+ if (last_output.find (antiprompt.c_str (), last_output.length () - antiprompt.length (), antiprompt.length ()) != std::string::npos) {
357
+ is_interacting = true ;
358
+ is_antiprompt = true ;
359
+ set_console_color (con_st, CONSOLE_COLOR_USER_INPUT);
360
+ fflush (stdout);
361
+ break ;
362
+ }
430
363
}
431
364
}
432
365
433
366
if (n_past > 0 && is_interacting) {
434
367
// potentially set color to indicate we are taking user input
435
- set_console_state (CONSOLE_STATE_USER_INPUT );
368
+ set_console_color (con_st, CONSOLE_COLOR_USER_INPUT );
436
369
437
370
if (params.instruct ) {
438
- n_consumed = embd_inp.size ();
439
- embd_inp.insert (embd_inp.end (), inp_pfx.begin (), inp_pfx.end ());
440
-
441
371
printf (" \n > " );
442
372
}
443
373
@@ -463,16 +393,28 @@ int main(int argc, char ** argv) {
463
393
} while (another_line);
464
394
465
395
// done taking input, reset color
466
- set_console_state (CONSOLE_STATE_DEFAULT );
396
+ set_console_color (con_st, CONSOLE_COLOR_DEFAULT );
467
397
468
- auto line_inp = ::llama_tokenize (ctx, buffer, false );
469
- embd_inp.insert (embd_inp.end (), line_inp.begin (), line_inp.end ());
398
+ // Add tokens to embd only if the input buffer is non-empty
399
+ // Entering a empty line lets the user pass control back
400
+ if (buffer.length () > 1 ) {
470
401
471
- if (params.instruct ) {
472
- embd_inp.insert (embd_inp.end (), inp_sfx.begin (), inp_sfx.end ());
473
- }
402
+ // instruct mode: insert instruction prefix
403
+ if (params.instruct && !is_antiprompt) {
404
+ n_consumed = embd_inp.size ();
405
+ embd_inp.insert (embd_inp.end (), inp_pfx.begin (), inp_pfx.end ());
406
+ }
474
407
475
- n_remain -= line_inp.size ();
408
+ auto line_inp = ::llama_tokenize (ctx, buffer, false );
409
+ embd_inp.insert (embd_inp.end (), line_inp.begin (), line_inp.end ());
410
+
411
+ // instruct mode: insert response suffix
412
+ if (params.instruct ) {
413
+ embd_inp.insert (embd_inp.end (), inp_sfx.begin (), inp_sfx.end ());
414
+ }
415
+
416
+ n_remain -= line_inp.size ();
417
+ }
476
418
477
419
input_noecho = true ; // do not echo this again
478
420
}
@@ -506,7 +448,7 @@ int main(int argc, char ** argv) {
506
448
llama_print_timings (ctx);
507
449
llama_free (ctx);
508
450
509
- set_console_state (CONSOLE_STATE_DEFAULT );
451
+ set_console_color (con_st, CONSOLE_COLOR_DEFAULT );
510
452
511
453
return 0 ;
512
454
}
0 commit comments