idle.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include "arg.h"
  2. #include "common.h"
  3. #include "log.h"
  4. #include "llama.h"
  5. #include <cmath>
  6. #include <cstdio>
  7. #include <cstring>
  8. #include <string>
  9. #include <thread>
  10. #include <vector>
  11. static void print_usage(int /*argc*/, char ** argv) {
  12. printf("\nexample usage:\n");
  13. printf("\n %s -m model.gguf [-ngl n_gpu_layers]\n", argv[0]);
  14. printf("\n");
  15. }
  16. int main(int argc, char ** argv) {
  17. common_params params;
  18. if (!common_params_parse(argc, argv, params, LLAMA_EXAMPLE_COMMON, print_usage)) {
  19. return 1;
  20. }
  21. common_init();
  22. // init LLM
  23. llama_backend_init();
  24. llama_numa_init(params.numa);
  25. // initialize the model
  26. llama_model_params model_params = common_model_params_to_llama(params);
  27. llama_model * model = llama_model_load_from_file(params.model.path.c_str(), model_params);
  28. if (model == NULL) {
  29. LOG_ERR("%s: error: unable to load model\n" , __func__);
  30. return 1;
  31. }
  32. const llama_vocab * vocab = llama_model_get_vocab(model);
  33. // we need just a dummy token to evaluate
  34. std::vector<llama_token> prompt_tokens(1, llama_vocab_bos(vocab));
  35. llama_context_params ctx_params = llama_context_default_params();
  36. ctx_params.n_ctx = 512;
  37. ctx_params.n_batch = 512;
  38. ctx_params.no_perf = false;
  39. llama_context * ctx = llama_init_from_model(model, ctx_params);
  40. if (ctx == NULL) {
  41. fprintf(stderr , "%s: error: failed to create the llama_context\n" , __func__);
  42. return 1;
  43. }
  44. llama_batch batch = llama_batch_get_one(prompt_tokens.data(), prompt_tokens.size());
  45. const int n_iters = 3;
  46. // warm-up
  47. llama_decode(ctx, batch);
  48. llama_memory_clear(llama_get_memory(ctx), true);
  49. llama_synchronize(ctx);
  50. for (int64_t t_pause_ms = 0; t_pause_ms <= 4000; t_pause_ms += 800) {
  51. double t_sum_us = 0.0;
  52. double t_sum2_us = 0.0;
  53. for (int i = 0; i < n_iters; i++) {
  54. // this pause is important - it simulates "idle GPU"
  55. std::this_thread::sleep_for(std::chrono::milliseconds(t_pause_ms));
  56. const int64_t t_start_us = llama_time_us();
  57. // this should take constant time
  58. llama_decode(ctx, batch);
  59. llama_synchronize(ctx);
  60. const int64_t t_end_us = llama_time_us();
  61. const double t_cur_us = t_end_us - t_start_us;
  62. #if 1
  63. // print individual decode times
  64. printf(" - decode time: %8.2f ms\n", t_cur_us / 1000);
  65. #endif
  66. t_sum_us += t_cur_us;
  67. t_sum2_us += t_cur_us * t_cur_us;
  68. llama_memory_clear(llama_get_memory(ctx), true);
  69. llama_synchronize(ctx); // just in case
  70. }
  71. const double t_avg_us = t_sum_us / n_iters;
  72. const double t_dev_us = sqrt((t_sum2_us / (n_iters - 1)) - (t_avg_us * t_avg_us * n_iters) / (n_iters - 1));
  73. printf("iters: %4d, pause: %5d ms, avg decode time: %8.2f +/- %4.2f ms\n", n_iters, (int) t_pause_ms, t_avg_us / 1000, t_dev_us / 1000);
  74. fflush(stdout);
  75. }
  76. llama_free(ctx);
  77. llama_model_free(model);
  78. return 0;
  79. }