diff --git a/backends/native/examples/hf_llm/runtime/LlmRunner.cpp b/backends/native/examples/hf_llm/runtime/LlmRunner.cpp index 7e8df20df1a..c7cfce656a8 100644 --- a/backends/native/examples/hf_llm/runtime/LlmRunner.cpp +++ b/backends/native/examples/hf_llm/runtime/LlmRunner.cpp @@ -349,14 +349,15 @@ struct Generation { // Prefills `prompt_tokens` from `start_position` in calls of at most // `max_chunk` tokens, then decodes one token per call until `limit` tokens or -// an EOS, streaming the text to stdout. With --warmup_prefill it prefills the -// prompt once beforehand, then clears `offgraph_cache` if there is one. +// an EOS, streaming the text to stdout unless `tokenizer` is null. With +// --warmup_prefill it prefills the prompt once beforehand, then clears +// `offgraph_cache` if there is one. Generation generate( ptn::EngineExecutable& executable, size_t logits_output, bool per_token_positions, size_t max_chunk, - ::tokenizers::Tiktoken& tokenizer, + const ::tokenizers::Tiktoken* tokenizer, const std::vector& prompt_tokens, int64_t start_position, size_t limit, @@ -488,19 +489,21 @@ Generation generate( size_t generated = 0; std::vector generated_ids; uint64_t previous_token = prompt_tokens.back(); - if (!FLAGS_interactive) { + if (tokenizer != nullptr && !FLAGS_interactive) { std::printf("text: "); } std::fflush(stdout); while (generated < limit && !eos_ids.contains(next_token)) { - auto decoded = tokenizer.decode(previous_token, next_token); - if (!decoded.ok()) { - throw std::runtime_error( - "failed to decode token: tokenizer error " + - std::to_string(static_cast(decoded.error()))); + if (tokenizer != nullptr) { + auto decoded = tokenizer->decode(previous_token, next_token); + if (!decoded.ok()) { + throw std::runtime_error( + "failed to decode token: tokenizer error " + + std::to_string(static_cast(decoded.error()))); + } + std::printf("%s", decoded.get().c_str()); + std::fflush(stdout); } - std::printf("%s", decoded.get().c_str()); - std::fflush(stdout); previous_token = next_token; if (FLAGS_print_token_ids) { generated_ids.push_back(next_token); @@ -517,7 +520,9 @@ Generation generate( ++generation.decode_steps; } } - std::printf("\n"); + if (tokenizer != nullptr) { + std::printf("\n"); + } generation.unfed_token = next_token; generation.ended_on_eos = eos_ids.contains(next_token); if (FLAGS_print_token_ids) { @@ -805,7 +810,8 @@ int run_llm( logits_output, per_token_positions, static_cast(token_shape[1]), - *tokenizer, + // The sample's tokens need not be in --tokenizer's vocabulary. + nullptr, prompt, 0, calls.size(), @@ -895,7 +901,7 @@ int run_llm( logits_output, per_token_positions, static_cast(token_shape[1]), - *tokenizer, + tokenizer.get(), tokens, position, limit, @@ -921,7 +927,7 @@ int run_llm( logits_output, per_token_positions, static_cast(token_shape[1]), - *tokenizer, + tokenizer.get(), prompt_tokens, 0, limit,