char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
2dcb7f74e
char/aliceai-t5-moe
1#include "ggml-opt.h" 2 3#include "ggml.h" 4#include "ggml-alloc.h" 5#include "ggml-backend.h" 6#include "ggml-impl.h" 7 8#include <algorithm> 9#include <cmath> 10#include <cstdint> 11#include <cinttypes> 12#include <map> 13#include <random> 14#include <vector> 15 16struct ggml_opt_dataset { 17struct ggml_context * ctx = nullptr ; 18ggml_backend_buffer_t buf = nullptr ; 19struct ggml_tensor * data = nullptr ; 20struct ggml_tensor * labels = nullptr ; 21 22int64_t ndata = -1 ; 23int64_t ndata_shard = -1 ; 24size_t nbs_data = -1 ; 25size_t nbs_labels = -1 ; 26 27 std::vector < int64_t > permutation ; 28}; 29 30struct ggml_opt_context { 31ggml_backend_sched_t backend_sched = nullptr ; 32ggml_cgraph * allocated_graph = nullptr ; 33ggml_cgraph * allocated_graph_copy = nullptr ; 34struct ggml_context * ctx_static = nullptr ; 35struct ggml_context * ctx_cpu = nullptr ; 36struct ggml_context * ctx_compute = nullptr ; 37struct ggml_context * ctx_copy = nullptr ; 38ggml_backend_buffer_t buf_static = nullptr ; 39ggml_backend_buffer_t buf_cpu = nullptr ; 40 std::mt19937 rng ; 41enum ggml_opt_loss_type loss_type ; 42enum ggml_opt_build_type build_type ; 43enum ggml_opt_build_type build_type_alloc ; 44 45struct ggml_tensor * inputs = nullptr ; 46struct ggml_tensor * outputs = nullptr ; 47struct ggml_tensor * labels = nullptr ; 48 49struct ggml_tensor * loss = nullptr ; 50struct ggml_tensor * pred = nullptr ; 51struct ggml_tensor * ncorrect = nullptr ; 52 53struct ggml_cgraph * gf = nullptr ; 54struct ggml_cgraph * gb_grad = nullptr ; 55struct ggml_cgraph * gb_opt = nullptr ; 56bool static_graphs = false; 57bool eval_ready = false; 58 std::vector < struct ggml_tensor *> grad_accs ; 59 std::vector < struct ggml_tensor *> grad_m ; 60 std::vector < struct ggml_tensor *> grad_v ; 61 62int64_t iter = 1 ; 63int32_t opt_period = 1 ; 64int32_t opt_i = 0 ; 65bool loss_per_datapoint = false; 66 67ggml_opt_get_optimizer_params get_opt_pars = nullptr ; 68void * get_opt_pars_ud = nullptr ; 69struct ggml_tensor * opt_step_params = nullptr ;// Stores output of get_opt_pars. 70 71enum ggml_opt_optimizer_type optimizer = GGML_OPT_OPTIMIZER_TYPE_ADAMW ; 72}; 73 74struct ggml_opt_result { 75int64_t ndata = 0 ; 76 std::vector < float > loss ; 77 std::vector < int32_t > pred ; 78int64_t ncorrect = 0 ; 79 80int64_t opt_period = -1 ; 81bool loss_per_datapoint = false; 82}; 83 84// ====== Dataset ====== 85 86ggml_opt_dataset_t ggml_opt_dataset_init ( 87enum ggml_type type_data , 88enum ggml_type type_label , 89int64_t ne_datapoint , 90int64_t ne_label , 91int64_t ndata , 92int64_t ndata_shard ) { 93GGML_ASSERT (ne_datapoint > 0 ); 94GGML_ASSERT (ne_label >=0 ); 95GGML_ASSERT (ndata > 0 ); 96GGML_ASSERT (ndata_shard > 0 ); 97 98ggml_opt_dataset_t result = new ggml_opt_dataset ; 99result -> ndata = ndata ; 100result -> ndata_shard = ndata_shard ; 101 102 { 103struct ggml_init_params params = { 104/*.mem_size =*/ 2 * ggml_tensor_overhead (), 105/*.mem_buffer =*/ nullptr , 106/*.no_alloc =*/ true, 107 }; 108result -> ctx = ggml_init (params ); 109 } 110 111result -> data = ggml_new_tensor_2d (result -> ctx ,type_data ,ne_datapoint ,ndata ); 112result -> nbs_data = ggml_nbytes (result -> data )* ndata_shard /ndata ; 113 114if (ne_label > 0 ) { 115result -> labels = ggml_new_tensor_2d (result -> ctx ,type_label ,ne_label ,ndata ); 116result -> nbs_labels = ggml_nbytes (result -> labels )* ndata_shard /ndata ; 117 }else { 118result -> labels = nullptr ; 119result -> nbs_labels = 0 ; 120 } 121 122result -> buf = ggml_backend_alloc_ctx_tensors_from_buft (result -> ctx ,ggml_backend_cpu_buffer_type ()); 123 124const int64_t nshards = ndata /ndata_shard ; 125result -> permutation .resize (nshards ); 126for (int64_t i = 0 ;i < nshards ;++ i ) { 127result -> permutation [i ]= i ; 128 } 129return result ; 130} 131 132void ggml_opt_dataset_free (ggml_opt_dataset_t dataset ) { 133ggml_backend_buffer_free (dataset -> buf ); 134ggml_free (dataset -> ctx ); 135delete dataset ; 136} 137 138int64_t ggml_opt_dataset_ndata (ggml_opt_dataset_t dataset ) { 139return dataset -> ndata ; 140} 141 142struct ggml_tensor * ggml_opt_dataset_data (ggml_opt_dataset_t dataset ) { 143return dataset -> data ; 144} 145 146struct ggml_tensor * ggml_opt_dataset_labels (ggml_opt_dataset_t dataset ) { 147return dataset -> labels ; 148} 149 150void ggml_opt_dataset_shuffle (ggml_opt_context_t opt_ctx ,ggml_opt_dataset_t dataset ,int64_t idata ) { 151GGML_ASSERT (idata <=dataset -> ndata ); 152 153if (idata < 0 ) { 154 std::shuffle (dataset -> permutation .begin (),dataset -> permutation .end (),opt_ctx -> rng ); 155return ; 156 } 157 158GGML_ASSERT (idata %dataset -> ndata_shard == 0 ); 159const int64_t ishard_max = idata /dataset -> ndata_shard ; 160 std::shuffle (dataset -> permutation .begin (),dataset -> permutation .begin ()+ ishard_max ,opt_ctx -> rng ); 161} 162 163void ggml_opt_dataset_get_batch (ggml_opt_dataset_t dataset ,struct ggml_tensor * data_batch ,struct ggml_tensor * labels_batch ,int64_t ibatch ) { 164GGML_ASSERT (data_batch && ggml_is_contiguous (data_batch )); 165GGML_ASSERT (!labels_batch || ggml_is_contiguous (labels_batch )); 166GGML_ASSERT ((labels_batch == nullptr )== (dataset -> labels == nullptr )); 167GGML_ASSERT (data_batch -> type == dataset -> data -> type ); 168GGML_ASSERT (!labels_batch || labels_batch -> type == dataset -> labels -> type ); 169 170const size_t nb_data_batch = ggml_nbytes (data_batch ); 171GGML_ASSERT (nb_data_batch %dataset -> nbs_data == 0 ); 172const int64_t shards_per_batch = nb_data_batch /dataset -> nbs_data ; 173 174if (labels_batch ) { 175const size_t nb_labels_batch = ggml_nbytes (labels_batch ); 176GGML_ASSERT (nb_labels_batch == shards_per_batch * dataset -> nbs_labels ); 177 } 178 179GGML_ASSERT ((ibatch + 1 )* shards_per_batch <=int64_t (dataset -> permutation .size ())); 180 181for (int64_t ishard_batch = 0 ;ishard_batch < shards_per_batch ;++ ishard_batch ) { 182const int64_t ishard = dataset -> permutation [ibatch * shards_per_batch + ishard_batch ]; 183 184const char * ptr_data = (const char * )dataset -> data -> data + ishard * dataset -> nbs_data ; 185ggml_backend_tensor_set (data_batch ,ptr_data ,ishard_batch * dataset -> nbs_data ,dataset -> nbs_data ); 186 187if (!labels_batch ) { 188continue ; 189 } 190 191const char * ptr_labels = (const char * )dataset -> labels -> data + ishard * dataset -> nbs_labels ; 192ggml_backend_tensor_set (labels_batch ,ptr_labels ,ishard_batch * dataset -> nbs_labels ,dataset -> nbs_labels ); 193 } 194} 195 196void ggml_opt_dataset_get_batch_host (ggml_opt_dataset_t dataset ,void * data_batch ,size_t nb_data_batch ,void * labels_batch ,int64_t ibatch ) { 197GGML_ASSERT ((labels_batch == nullptr )== (dataset -> labels == nullptr )); 198GGML_ASSERT (nb_data_batch %dataset -> nbs_data == 0 ); 199 200const int64_t shards_per_batch = nb_data_batch /dataset -> nbs_data ; 201 202GGML_ASSERT ((ibatch + 1 )* shards_per_batch <=int64_t (dataset -> permutation .size ())); 203 204for (int64_t ishard_batch = 0 ;ishard_batch < shards_per_batch ;++ ishard_batch ) { 205const int64_t ishard = dataset -> permutation [ibatch * shards_per_batch + ishard_batch ]; 206 207const char * ptr_data = (const char * )dataset -> data -> data + ishard * dataset -> nbs_data ; 208char * ptr_data_batch = (char * )data_batch + ishard_batch * dataset -> nbs_data ; 209memcpy (ptr_data_batch ,ptr_data ,dataset -> nbs_data ); 210 211if (!labels_batch ) { 212continue ; 213 } 214 215const char * ptr_labels = (const char * )dataset -> labels -> data + ishard * dataset -> nbs_labels ; 216char * ptr_labels_batch = (char * )labels_batch + ishard_batch * dataset -> nbs_labels ; 217memcpy (ptr_labels_batch ,ptr_labels ,dataset -> nbs_labels ); 218 } 219} 220 221// ====== Model / Context ====== 222 223struct ggml_opt_optimizer_params ggml_opt_get_default_optimizer_params (void * userdata ) { 224GGML_UNUSED (userdata ); 225 226ggml_opt_optimizer_params result ; 227 228result .adamw .alpha = 0.001f ; 229result .adamw .beta1 = 0.9f ; 230result .adamw .beta2 = 0.999f ; 231result .adamw .eps = 1e-8f ; 232result .adamw .wd = 0.0f ; 233 234result .sgd .alpha = 1e-3f ; 235result .sgd .wd = 0.0f ; 236 237return result ; 238} 239 240 241struct ggml_opt_optimizer_params ggml_opt_get_constant_optimizer_params (void * userdata ) { 242return * ((struct ggml_opt_optimizer_params * )userdata ); 243} 244 245struct ggml_opt_params ggml_opt_default_params ( 246ggml_backend_sched_t backend_sched , 247enum ggml_opt_loss_type loss_type ) { 248return { 249/*backend_sched =*/ backend_sched , 250/*ctx_compute =*/ nullptr , 251/*inputs =*/ nullptr , 252/*logits =*/ nullptr , 253/*loss_type =*/ loss_type , 254/*build_type =*/ GGML_OPT_BUILD_TYPE_OPT , 255/*opt_period =*/ 1 , 256/*get_opt_pars =*/ ggml_opt_get_default_optimizer_params , 257/*get_opt_pars_ud =*/ nullptr , 258/*optimizer =*/ GGML_OPT_OPTIMIZER_TYPE_ADAMW , 259 }; 260} 261 262static ggml_tensor * map_tensor (std::map < ggml_tensor * ,ggml_tensor *> & tensor_map ,ggml_context * ctx ,ggml_tensor * tensor ) { 263if (!tensor ) { 264return nullptr ; 265 } 266 267if (tensor_map .find (tensor )!= tensor_map .end ()) { 268return tensor_map [tensor ]; 269 } 270 271ggml_tensor * new_tensor = ggml_dup_tensor (ctx ,tensor ); 272tensor_map [tensor ]= new_tensor ; 273 274new_tensor -> op = tensor -> op ; 275for (int i = 0 ;i < GGML_MAX_DIMS ;i ++ ) { 276new_tensor -> nb [i ]= tensor -> nb [i ]; 277 } 278new_tensor -> flags = tensor -> flags ; 279memcpy (new_tensor -> op_params ,tensor -> op_params ,sizeof (tensor -> op_params )); 280strcpy (new_tensor -> name ,tensor -> name ); 281new_tensor -> data = tensor -> data ; 282new_tensor -> buffer = tensor -> buffer ; 283new_tensor -> extra = tensor -> extra ; 284new_tensor -> view_offs = tensor -> view_offs ; 285new_tensor -> view_src = map_tensor (tensor_map ,ctx ,tensor -> view_src ); 286for (int i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 287new_tensor -> src [i ]= map_tensor (tensor_map ,ctx ,tensor -> src [i ]); 288 } 289 290return new_tensor ; 291} 292 293static ggml_cgraph * dup_graph (ggml_context * ctx ,ggml_cgraph * src ) { 294 std::map < ggml_tensor * ,ggml_tensor *> tensor_map ; 295 296ggml_cgraph * dst = ggml_new_graph_custom (ctx ,src -> size ,/*grads =*/ true); 297 298for (int i = 0 ;i < src -> n_leafs ;i ++ ) { 299ggml_build_forward_expand (dst ,map_tensor (tensor_map ,ctx ,src -> leafs [i ])); 300 } 301GGML_ASSERT (dst -> n_leafs == src -> n_leafs ); 302for (int i = 0 ;i < src -> n_nodes ;i ++ ) { 303ggml_build_forward_expand (dst ,map_tensor (tensor_map ,ctx ,src -> nodes [i ])); 304 } 305GGML_ASSERT (dst -> n_nodes == src -> n_nodes ); 306for (int i = 0 ;i < src -> n_nodes ;++ i ) { 307const size_t igrad_src = ggml_hash_find (& src -> visited_hash_set ,src -> nodes [i ]); 308const size_t igrad_dst = ggml_hash_find (& dst -> visited_hash_set ,dst -> nodes [i ]); 309 310GGML_ASSERT (igrad_src != GGML_HASHSET_FULL ); 311GGML_ASSERT (ggml_bitset_get (src -> visited_hash_set .used ,igrad_src )); 312GGML_ASSERT (igrad_dst != GGML_HASHSET_FULL ); 313GGML_ASSERT (ggml_bitset_get (dst -> visited_hash_set .used ,igrad_dst )); 314 315dst -> grads [igrad_dst ]= src -> grads [igrad_src ]; 316dst -> grad_accs [igrad_dst ]= src -> grad_accs [igrad_src ]; 317 } 318 319return dst ; 320} 321 322static void ggml_opt_build (ggml_opt_context_t opt_ctx ) { 323GGML_ASSERT (opt_ctx -> ctx_compute && "no compute context set, either use static graphs or set one with ggml_opt_prepare_alloc" ); 324GGML_ASSERT ((!opt_ctx -> static_graphs || opt_ctx -> inputs -> data )&& "when using static graphs the inputs must be allocated statically" ); 325 326const enum ggml_opt_optimizer_type optimizer = opt_ctx -> optimizer ; 327 328const bool accumulate = opt_ctx -> build_type_alloc >=GGML_OPT_BUILD_TYPE_GRAD && 329 !(opt_ctx -> static_graphs && opt_ctx -> build_type_alloc == GGML_OPT_BUILD_TYPE_OPT && opt_ctx -> opt_period == 1 ); 330 331const bool need_momenta = opt_ctx -> build_type_alloc == GGML_OPT_BUILD_TYPE_OPT && 332opt_ctx -> optimizer == GGML_OPT_OPTIMIZER_TYPE_ADAMW ; 333 334ggml_set_input (opt_ctx -> inputs ); 335ggml_set_output (opt_ctx -> outputs ); 336 337int n_param = 0 ; 338for (int i = 0 ;i < opt_ctx -> gf -> n_nodes ;++ i ) { 339const struct ggml_tensor * node = opt_ctx -> gf -> nodes [i ]; 340if (node -> flags & GGML_TENSOR_FLAG_PARAM ) { 341n_param ++ ; 342 } 343GGML_ASSERT (!(node -> flags & GGML_TENSOR_FLAG_LOSS )&& "support for extra loss terms not implemented" ); 344 } 345 346if (!opt_ctx -> ctx_static ) { 347// The static context is used for: 348// - gradients (1 per loss, 1 tensor per param if using gradient accumulation) 349// - optimizer momenta (2 tensors per param) 350// - labels (if using static graphs) 351// - loss (if using static graphs, up to 5 tensors) 352// - pred (if using static graphs) 353// - ncorrect (if using static graphs, 2 tensors). 354constexpr size_t n_loss = 1 ; 355const size_t tensors_per_param = (accumulate ?1 :0 )+ (need_momenta ?2 :0 ); 356const size_t tensors_const = opt_ctx -> static_graphs ?9 :0 ; 357const size_t size_meta = (n_loss + tensors_per_param * n_param + tensors_const )* ggml_tensor_overhead (); 358struct ggml_init_params params = { 359/*.mem_size =*/ size_meta , 360/*.mem_buffer =*/ nullptr , 361/*.no_alloc =*/ true, 362 }; 363opt_ctx -> ctx_static = ggml_init (params ); 364 } 365GGML_ASSERT (opt_ctx -> build_type <=opt_ctx -> build_type_alloc ); 366 367 { 368// The cpu context is allocated statically if using static graphs, dynamically otherwise. 369// It is used for: 370// - optimizer parameters (1 shared for all optimizer invocations) 371const size_t size_meta = 1 * ggml_tensor_overhead (); 372struct ggml_init_params params = { 373/*.mem_size =*/ size_meta , 374/*.mem_buffer =*/ nullptr , 375/*.no_alloc =*/ true, 376 }; 377ggml_free (opt_ctx -> ctx_cpu ); 378opt_ctx -> ctx_cpu = ggml_init (params ); 379 380ggml_backend_buffer_free (opt_ctx -> buf_cpu ); 381opt_ctx -> buf_cpu = nullptr ; 382 } 383 384struct ggml_context * ctx_results = opt_ctx -> static_graphs ?opt_ctx -> ctx_static :opt_ctx -> ctx_compute ; 385 386switch (opt_ctx -> loss_type ) { 387case GGML_OPT_LOSS_TYPE_MEAN : { 388opt_ctx -> loss = ggml_sum (ctx_results ,opt_ctx -> outputs ); 389ggml_set_name (opt_ctx -> loss ,"loss_sum" ); 390const float scale = 1.0f / (opt_ctx -> opt_period * ggml_nelements (opt_ctx -> outputs )); 391opt_ctx -> loss = ggml_scale (ctx_results ,opt_ctx -> loss ,scale ); 392ggml_set_name (opt_ctx -> loss ,"loss_mean" ); 393opt_ctx -> loss_per_datapoint = true; 394break ; 395 } 396case GGML_OPT_LOSS_TYPE_SUM : { 397opt_ctx -> loss = ggml_sum (ctx_results ,opt_ctx -> outputs ); 398ggml_set_name (opt_ctx -> loss ,"loss_sum" ); 399opt_ctx -> loss_per_datapoint = false; 400break ; 401 } 402case GGML_OPT_LOSS_TYPE_CROSS_ENTROPY : { 403opt_ctx -> labels = ggml_dup_tensor (ctx_results ,opt_ctx -> outputs ); 404ggml_set_input (opt_ctx -> labels ); 405ggml_set_name (opt_ctx -> labels ,"labels" ); 406opt_ctx -> loss = ggml_cross_entropy_loss (ctx_results ,opt_ctx -> outputs ,opt_ctx -> labels ); 407ggml_set_name (opt_ctx -> loss ,"loss_cross_entropy" ); 408if (opt_ctx -> opt_period > 1 ) { 409opt_ctx -> loss = ggml_scale (ctx_results ,opt_ctx -> loss ,1.0f /opt_ctx -> opt_period ); 410ggml_set_name (opt_ctx -> loss ,"loss_cross_entropy_scaled" ); 411 } 412opt_ctx -> loss_per_datapoint = true; 413break ; 414 } 415case GGML_OPT_LOSS_TYPE_MEAN_SQUARED_ERROR : { 416opt_ctx -> labels = ggml_dup_tensor (ctx_results ,opt_ctx -> outputs ); 417ggml_set_input (opt_ctx -> labels ); 418ggml_set_name (opt_ctx -> labels ,"labels" ); 419opt_ctx -> loss = ggml_sub (ctx_results ,opt_ctx -> outputs ,opt_ctx -> labels ); 420ggml_set_name (opt_ctx -> loss ,"loss_error" ); 421opt_ctx -> loss = ggml_sqr (ctx_results ,opt_ctx -> loss ); 422ggml_set_name (opt_ctx -> loss ,"loss_squared_error" ); 423opt_ctx -> loss = ggml_sum (ctx_results ,opt_ctx -> loss ); 424ggml_set_name (opt_ctx -> loss ,"loss_sum_squared_error" ); 425const float scale = 1.0f / (opt_ctx -> opt_period * ggml_nelements (opt_ctx -> outputs )); 426opt_ctx -> loss = ggml_scale (ctx_results ,opt_ctx -> loss ,scale ); 427ggml_set_name (opt_ctx -> loss ,"loss_mean_squared_error" ); 428opt_ctx -> loss_per_datapoint = true; 429break ; 430 } 431 } 432ggml_set_output (opt_ctx -> loss ); 433ggml_set_loss (opt_ctx -> loss ); 434ggml_build_forward_expand (opt_ctx -> gf ,opt_ctx -> loss ); 435 436if (opt_ctx -> loss_type == GGML_OPT_LOSS_TYPE_CROSS_ENTROPY ) { 437opt_ctx -> pred = ggml_argmax (ctx_results ,opt_ctx -> outputs ); 438ggml_set_name (opt_ctx -> pred ,"pred" ); 439ggml_set_output (opt_ctx -> pred ); 440ggml_build_forward_expand (opt_ctx -> gf ,opt_ctx -> pred ); 441 442opt_ctx -> ncorrect = ggml_count_equal (ctx_results ,opt_ctx -> pred ,ggml_argmax (ctx_results ,opt_ctx -> labels )); 443ggml_set_name (opt_ctx -> ncorrect ,"ncorrect" ); 444ggml_set_output (opt_ctx -> ncorrect ); 445ggml_build_forward_expand (opt_ctx -> gf ,opt_ctx -> ncorrect ); 446 } 447 448if (opt_ctx -> buf_static ) { 449if (opt_ctx -> build_type == GGML_OPT_BUILD_TYPE_FORWARD ) { 450return ; 451 } 452 }else if (opt_ctx -> build_type_alloc == GGML_OPT_BUILD_TYPE_FORWARD ) { 453opt_ctx -> buf_static = ggml_backend_alloc_ctx_tensors ( 454opt_ctx -> ctx_static ,ggml_backend_sched_get_backend (opt_ctx -> backend_sched ,0 )); 455return ; 456 } 457 458if (opt_ctx -> grad_accs .empty ()) { 459GGML_ASSERT (opt_ctx -> build_type_alloc >=GGML_OPT_BUILD_TYPE_GRAD ); 460 461const int n_nodes = opt_ctx -> gf -> n_nodes ; 462opt_ctx -> grad_accs .resize (n_nodes ); 463for (int i = 0 ;i < n_nodes ;++ i ) { 464ggml_tensor * node = opt_ctx -> gf -> nodes [i ]; 465if ((accumulate && (node -> flags & GGML_TENSOR_FLAG_PARAM ))|| (node -> flags & GGML_TENSOR_FLAG_LOSS )) { 466opt_ctx -> grad_accs [i ]= ggml_new_tensor (opt_ctx -> ctx_static ,GGML_TYPE_F32 ,GGML_MAX_DIMS ,node -> ne ); 467 }else { 468opt_ctx -> grad_accs [i ]= nullptr ; 469 } 470 } 471 472if (need_momenta && opt_ctx -> build_type_alloc >=GGML_OPT_BUILD_TYPE_OPT ) { 473opt_ctx -> grad_m .resize (n_nodes ); 474opt_ctx -> grad_v .resize (n_nodes ); 475for (int i = 0 ;i < n_nodes ;++ i ) { 476ggml_tensor * node = opt_ctx -> gf -> nodes [i ]; 477if (node -> flags & GGML_TENSOR_FLAG_PARAM ) { 478opt_ctx -> grad_m [i ]= ggml_new_tensor (opt_ctx -> ctx_static ,GGML_TYPE_F32 ,GGML_MAX_DIMS ,node -> ne ); 479opt_ctx -> grad_v [i ]= ggml_new_tensor (opt_ctx -> ctx_static ,GGML_TYPE_F32 ,GGML_MAX_DIMS ,node -> ne ); 480 }else { 481opt_ctx -> grad_m [i ]= nullptr ; 482opt_ctx -> grad_v [i ]= nullptr ; 483 } 484 } 485 } 486 } 487 488// gb_grad == graph backward gradients, forward pass, then backward pass to calculate gradients. 489opt_ctx -> gb_grad = ggml_graph_dup (opt_ctx -> ctx_compute ,opt_ctx -> gf ,/*force_grads =*/ true); 490ggml_build_backward_expand (opt_ctx -> ctx_compute ,opt_ctx -> gb_grad ,opt_ctx -> grad_accs .data ()); 491 492if (opt_ctx -> buf_static ) { 493if (opt_ctx -> build_type == GGML_OPT_BUILD_TYPE_GRAD ) { 494return ; 495 } 496 }else if (opt_ctx -> build_type_alloc == GGML_OPT_BUILD_TYPE_GRAD ) { 497opt_ctx -> buf_static = ggml_backend_alloc_ctx_tensors (opt_ctx -> ctx_static ,ggml_backend_sched_get_backend (opt_ctx -> backend_sched ,0 )); 498ggml_graph_reset (opt_ctx -> gb_grad ); 499 } 500 501GGML_ASSERT (opt_ctx -> build_type_alloc == GGML_OPT_BUILD_TYPE_OPT ); 502 503// gb_opt == graph backward optimize, forward pass, then backward pass to calculate gradients, then optimizer step. 504opt_ctx -> gb_opt = ggml_graph_dup (opt_ctx -> ctx_compute ,opt_ctx -> gb_grad ,/*force_grads =*/ true); 505 506opt_ctx -> opt_step_params = ggml_new_tensor_1d (opt_ctx -> ctx_cpu ,GGML_TYPE_F32 ,need_momenta ?7 :2 ); 507ggml_tensor * adamw_params = opt_ctx -> opt_step_params ; 508ggml_set_input (adamw_params ); 509const char * optimizer_name = ggml_opt_optimizer_name (opt_ctx -> optimizer ); 510ggml_format_name (adamw_params ,"%s_params" ,optimizer_name ); 511for (int i = opt_ctx -> gf -> n_nodes - 1 ;i >=0 ;-- i ) { 512struct ggml_tensor * node = opt_ctx -> gb_opt -> nodes [i ]; 513struct ggml_tensor * grad = ggml_graph_get_grad (opt_ctx -> gb_opt ,node ); 514 515if (grad && (node -> flags & GGML_TENSOR_FLAG_PARAM )) { 516struct ggml_tensor * m = nullptr ; 517struct ggml_tensor * v = nullptr ; 518if (need_momenta ) { 519m = opt_ctx -> grad_m [i ]; 520v = opt_ctx -> grad_v [i ]; 521ggml_format_name (m ,"AdamW m for %s" ,node -> name ); 522ggml_format_name (v ,"AdamW v for %s" ,node -> name ); 523 } 524struct ggml_tensor * opt_step ; 525switch (optimizer ) { 526case GGML_OPT_OPTIMIZER_TYPE_ADAMW : 527opt_step = ggml_opt_step_adamw (opt_ctx -> ctx_compute ,node ,grad ,m ,v ,adamw_params ); 528break ; 529case GGML_OPT_OPTIMIZER_TYPE_SGD : 530opt_step = ggml_opt_step_sgd (opt_ctx -> ctx_compute ,node ,grad ,adamw_params ); 531break ; 532default : 533GGML_ABORT ("fatal error" ); 534 } 535ggml_format_name (opt_step ,"%s step for %s" ,optimizer_name ,node -> name ); 536ggml_build_forward_expand (opt_ctx -> gb_opt ,opt_step ); 537 } 538 } 539 540if (!opt_ctx -> buf_static ) { 541opt_ctx -> buf_static = ggml_backend_alloc_ctx_tensors ( 542opt_ctx -> ctx_static ,ggml_backend_sched_get_backend (opt_ctx -> backend_sched ,0 )); 543ggml_graph_reset (opt_ctx -> gb_opt ); 544 } 545 546opt_ctx -> buf_cpu = ggml_backend_alloc_ctx_tensors_from_buft (opt_ctx -> ctx_cpu ,ggml_backend_cpu_buffer_type ()); 547} 548 549ggml_opt_context_t ggml_opt_init (struct ggml_opt_params params ) { 550ggml_opt_context_t result = new struct ggml_opt_context ; 551result -> backend_sched = params .backend_sched ; 552result -> ctx_compute = params .ctx_compute ; 553result -> loss_type = params .loss_type ; 554result -> build_type = params .build_type ; 555result -> build_type_alloc = params .build_type ; 556result -> inputs = params .inputs ; 557result -> outputs = params .outputs ; 558result -> opt_period = params .opt_period ; 559result -> get_opt_pars = params .get_opt_pars ; 560result -> get_opt_pars_ud = params .get_opt_pars_ud ; 561result -> optimizer = params .optimizer ; 562 563GGML_ASSERT (result -> opt_period >=1 ); 564 565result -> static_graphs = result -> ctx_compute ; 566 567if (!result -> static_graphs ) { 568GGML_ASSERT (!result -> inputs ); 569GGML_ASSERT (!result -> outputs ); 570return result ; 571 } 572 573GGML_ASSERT (result -> inputs ); 574GGML_ASSERT (result -> outputs ); 575 576result -> gf = ggml_new_graph_custom (result -> ctx_compute ,GGML_DEFAULT_GRAPH_SIZE ,/*grads =*/ true);// Forward pass. 577ggml_build_forward_expand (result -> gf ,result -> outputs ); 578 579ggml_opt_build (result ); 580 581return result ; 582} 583 584void ggml_opt_free (ggml_opt_context_t opt_ctx ) { 585if (opt_ctx == nullptr ) { 586return ; 587 } 588ggml_backend_buffer_free (opt_ctx -> buf_static ); 589ggml_backend_buffer_free (opt_ctx -> buf_cpu ); 590ggml_free (opt_ctx -> ctx_static ); 591ggml_free (opt_ctx -> ctx_cpu ); 592ggml_free (opt_ctx -> ctx_copy ); 593delete opt_ctx ; 594} 595 596void ggml_opt_reset (ggml_opt_context_t opt_ctx ,bool optimizer ) { 597if (optimizer ) { 598ggml_graph_reset (opt_ctx -> gb_opt ); 599opt_ctx -> iter = 1 ; 600 }else { 601ggml_graph_reset (opt_ctx -> gb_grad ); 602 } 603} 604 605bool ggml_opt_static_graphs (ggml_opt_context_t opt_ctx ) { 606return opt_ctx -> static_graphs ; 607} 608 609struct ggml_tensor * ggml_opt_inputs (ggml_opt_context_t opt_ctx ) { 610return opt_ctx -> inputs ; 611} 612 613struct ggml_tensor * ggml_opt_outputs (ggml_opt_context_t opt_ctx ) { 614return opt_ctx -> outputs ; 615} 616 617struct ggml_tensor * ggml_opt_labels (ggml_opt_context_t opt_ctx ) { 618return opt_ctx -> labels ; 619} 620 621struct ggml_tensor * ggml_opt_loss (ggml_opt_context_t opt_ctx ) { 622return opt_ctx -> loss ; 623} 624 625struct ggml_tensor * ggml_opt_pred (ggml_opt_context_t opt_ctx ) { 626return opt_ctx -> pred ; 627} 628 629struct ggml_tensor * ggml_opt_ncorrect (ggml_opt_context_t opt_ctx ) { 630return opt_ctx -> ncorrect ; 631} 632 633struct ggml_tensor * ggml_opt_grad_acc (ggml_opt_context_t opt_ctx ,struct ggml_tensor * node ) { 634return ggml_graph_get_grad_acc (opt_ctx -> gb_opt ,node ); 635} 636 637// ====== Optimization Result ====== 638 639ggml_opt_result_t ggml_opt_result_init () { 640return new ggml_opt_result ; 641} 642 643void ggml_opt_result_free (ggml_opt_result_t result ) { 644delete result ; 645} 646 647void ggml_opt_result_reset (ggml_opt_result_t result ) { 648result -> ndata = 0 ; 649result -> loss .clear (); 650result -> pred .clear (); 651result -> ncorrect = 0 ; 652} 653 654void ggml_opt_result_ndata (ggml_opt_result_t result ,int64_t * ndata ) { 655* ndata = result -> ndata ; 656} 657 658void ggml_opt_result_loss (ggml_opt_result_t result ,double * loss ,double * unc ) { 659const int64_t nbatches = result -> loss .size ();// Number of physical batches. 660 661if (nbatches == 0 ) { 662* loss = 0.0 ; 663* unc = NAN ; 664return ; 665 } 666 667double sum = 0.0 ; 668double sum_squared = 0.0 ; 669 670for (const float & loss :result -> loss ) { 671// If the loss is per datapoint it was scaled by 1.0f/opt_period for each physical batch. 672const float loss_scaled = result -> loss_per_datapoint ?loss * result -> opt_period :loss ; 673sum += loss_scaled ; 674sum_squared += loss_scaled * loss_scaled ; 675 } 676 677const double mean = sum /nbatches ; 678* loss = result -> loss_per_datapoint ?mean :sum ; 679 680if (!unc ) { 681return ; 682 } 683 684if (nbatches < 2 ) { 685* unc = NAN ; 686return ; 687 } 688 689const double var_sum = sum_squared /nbatches - mean * mean ;// variance without Bessel's correction, i.e. nbatches/(nbatches-1) 690* unc = result -> loss_per_datapoint ?sqrt (var_sum / (nbatches - 1 )) :sqrt (var_sum * nbatches /(nbatches - 1 )); 691} 692 693void ggml_opt_result_pred (ggml_opt_result_t result ,int32_t * pred ) { 694for (size_t i = 0 ;i < result -> pred .size ();++ i ) { 695pred [i ]= result -> pred [i ]; 696 } 697} 698 699void ggml_opt_result_accuracy (ggml_opt_result_t result ,double * accuracy ,double * unc ) { 700* accuracy = result -> ncorrect >=0 ?double (result -> ncorrect ) /double (result -> ndata ) :NAN ; 701 702if (!unc ) { 703return ; 704 } 705 706* unc = result -> ncorrect >=0 && result -> ndata >=2 ? 707sqrt ((* accuracy )* (1.0 - (* accuracy )) /double (result -> ndata - 1 )) :NAN ; 708} 709 710// ====== Computation ====== 711 712void ggml_opt_prepare_alloc ( 713ggml_opt_context_t opt_ctx , 714struct ggml_context * ctx_compute , 715struct ggml_cgraph * gf , 716struct ggml_tensor * inputs , 717struct ggml_tensor * outputs ) { 718GGML_ASSERT (!opt_ctx -> static_graphs ); 719opt_ctx -> ctx_compute = ctx_compute ; 720opt_ctx -> gf = gf ; 721opt_ctx -> inputs = inputs ; 722opt_ctx -> outputs = outputs ; 723} 724 725void ggml_opt_alloc (ggml_opt_context_t opt_ctx ,bool backward ) { 726GGML_ASSERT (!opt_ctx -> eval_ready ); 727if (opt_ctx -> build_type == GGML_OPT_BUILD_TYPE_OPT && opt_ctx -> opt_period > 1 && opt_ctx -> opt_i == 0 ) { 728ggml_graph_reset (opt_ctx -> gb_grad ); 729 } 730if (backward ) { 731const int32_t opt_i_next = (opt_ctx -> opt_i + 1 ) %opt_ctx -> opt_period ; 732opt_ctx -> build_type = opt_i_next == 0 ?GGML_OPT_BUILD_TYPE_OPT :GGML_OPT_BUILD_TYPE_GRAD ; 733 }else { 734opt_ctx -> build_type = GGML_OPT_BUILD_TYPE_FORWARD ; 735 } 736 737if (!opt_ctx -> static_graphs ) { 738ggml_opt_build (opt_ctx ); 739 } 740 741struct ggml_cgraph * graph = nullptr ; 742switch (opt_ctx -> build_type ) { 743case GGML_OPT_BUILD_TYPE_FORWARD : { 744graph = opt_ctx -> gf ; 745 }break ; 746case GGML_OPT_BUILD_TYPE_GRAD : { 747graph = opt_ctx -> gb_grad ; 748 }break ; 749case GGML_OPT_BUILD_TYPE_OPT : { 750graph = opt_ctx -> gb_opt ; 751 }break ; 752 } 753GGML_ASSERT (graph ); 754 755if (opt_ctx -> allocated_graph == graph ) { 756opt_ctx -> eval_ready = true; 757return ; 758 } 759 760ggml_backend_sched_reset (opt_ctx -> backend_sched );// clear allocation of previous graph 761 762if (opt_ctx -> static_graphs ) { 763ggml_init_params params = { 764/*.mem_size =*/ graph -> size * ggml_tensor_overhead ()+ ggml_graph_overhead_custom (graph -> size ,graph -> grads ), 765/*.mem_buffer =*/ nullptr , 766/*.no_alloc =*/ true, 767 }; 768ggml_free (opt_ctx -> ctx_copy ); 769opt_ctx -> ctx_copy = ggml_init (params ); 770 771opt_ctx -> allocated_graph_copy = dup_graph (opt_ctx -> ctx_copy ,graph ); 772 }else { 773opt_ctx -> allocated_graph_copy = graph ; 774 } 775 776ggml_backend_sched_alloc_graph (opt_ctx -> backend_sched ,opt_ctx -> allocated_graph_copy ); 777opt_ctx -> allocated_graph = graph ; 778 779opt_ctx -> eval_ready = true; 780} 781 782void ggml_opt_eval (ggml_opt_context_t opt_ctx ,ggml_opt_result_t result ) { 783GGML_ASSERT (opt_ctx -> eval_ready ); 784if (opt_ctx -> allocated_graph == opt_ctx -> gb_opt ) { 785const ggml_opt_optimizer_params & opt_pars = opt_ctx -> get_opt_pars (opt_ctx -> get_opt_pars_ud ); 786 787switch (opt_ctx -> optimizer ) { 788case GGML_OPT_OPTIMIZER_TYPE_ADAMW : { 789GGML_ASSERT (opt_pars .adamw .alpha > 0.0f ); 790GGML_ASSERT (opt_pars .adamw .beta1 >=0.0f ); 791GGML_ASSERT (opt_pars .adamw .beta1 <=1.0f ); 792GGML_ASSERT (opt_pars .adamw .beta2 >=0.0f ); 793GGML_ASSERT (opt_pars .adamw .beta2 <=1.0f ); 794GGML_ASSERT (opt_pars .adamw .eps >=0.0f ); 795GGML_ASSERT (opt_pars .adamw .wd >=0.0f ); 796GGML_ASSERT (opt_pars .adamw .wd <=1.0f ); 797 798// beta1, beta2 after applying warmup 799const float beta1h = 1.0f / (1.0f - powf (opt_pars .adamw .beta1 ,opt_ctx -> iter )); 800const float beta2h = 1.0f / (1.0f - powf (opt_pars .adamw .beta2 ,opt_ctx -> iter )); 801 802float * adamw_par_data = ggml_get_data_f32 (opt_ctx -> opt_step_params ); 803adamw_par_data [0 ]= opt_pars .adamw .alpha ; 804adamw_par_data [1 ]= opt_pars .adamw .beta1 ; 805adamw_par_data [2 ]= opt_pars .adamw .beta2 ; 806adamw_par_data [3 ]= opt_pars .adamw .eps ; 807adamw_par_data [4 ]= opt_pars .adamw .wd ; 808adamw_par_data [5 ]= beta1h ; 809adamw_par_data [6 ]= beta2h ; 810 }break ; 811case GGML_OPT_OPTIMIZER_TYPE_SGD : { 812GGML_ASSERT (opt_pars .sgd .alpha > 0.0f ); 813GGML_ASSERT (opt_pars .sgd .wd >=0.0f ); 814GGML_ASSERT (opt_pars .sgd .wd <=1.0f ); 815float * sgd = ggml_get_data_f32 (opt_ctx -> opt_step_params ); 816sgd [0 ]= opt_pars .sgd .alpha ; 817sgd [1 ]= opt_pars .sgd .wd ; 818 }break ; 819default : 820GGML_ABORT ("fatal error" ); 821 } 822 } 823 824ggml_backend_sched_graph_compute (opt_ctx -> backend_sched ,opt_ctx -> allocated_graph_copy ); 825opt_ctx -> iter += opt_ctx -> allocated_graph == opt_ctx -> gb_opt ; 826opt_ctx -> opt_i = (opt_ctx -> opt_i + 1 ) %opt_ctx -> opt_period ; 827 828if (!opt_ctx -> static_graphs ) { 829opt_ctx -> gf = nullptr ; 830opt_ctx -> gb_grad = nullptr ; 831opt_ctx -> gb_opt = nullptr ; 832opt_ctx -> allocated_graph = nullptr ; 833opt_ctx -> allocated_graph_copy = nullptr ; 834 } 835 836opt_ctx -> eval_ready = false; 837 838if (!result ) { 839return ; 840 } 841 842if (result -> ndata == 0 ) { 843result -> loss_per_datapoint = opt_ctx -> loss_per_datapoint ; 844result -> opt_period = opt_ctx -> opt_period ; 845 }else { 846GGML_ASSERT (result -> loss_per_datapoint == opt_ctx -> loss_per_datapoint ); 847GGML_ASSERT (result -> opt_period == opt_ctx -> opt_period ); 848 } 849 850const int64_t ndata = opt_ctx -> outputs -> ne [1 ]; 851GGML_ASSERT (result -> ndata == ndata * int64_t (result -> loss .size ())&& "varying batch size not supported" ); 852result -> ndata += ndata ; 853 854GGML_ASSERT (ggml_is_scalar (opt_ctx -> loss )); 855GGML_ASSERT (opt_ctx -> loss -> type == GGML_TYPE_F32 ); 856float loss ; 857ggml_backend_tensor_get (opt_ctx -> loss ,& loss ,0 ,ggml_nbytes (opt_ctx -> loss )); 858result -> loss .push_back (loss ); 859 860if (opt_ctx -> pred ) { 861GGML_ASSERT (opt_ctx -> pred -> type == GGML_TYPE_I32 ); 862 std::vector < int32_t > pred (ndata ); 863ggml_backend_tensor_get (opt_ctx -> pred ,pred .data (),0 ,ggml_nbytes (opt_ctx -> pred )); 864result -> pred .insert (result -> pred .end (),pred .begin (),pred .end ()); 865 } 866 867if (!opt_ctx -> ncorrect || result -> ncorrect < 0 ) { 868result -> ncorrect = -1 ; 869return ; 870 } 871 872GGML_ASSERT (ggml_is_scalar (opt_ctx -> ncorrect )); 873GGML_ASSERT (opt_ctx -> ncorrect -> type == GGML_TYPE_I64 ); 874int64_t ncorrect ; 875ggml_backend_tensor_get (opt_ctx -> ncorrect ,& ncorrect ,0 ,ggml_nbytes (opt_ctx -> ncorrect )); 876result -> ncorrect += ncorrect ; 877} 878 879// ====== High-Level Functions ====== 880 881void ggml_opt_epoch ( 882ggml_opt_context_t opt_ctx , 883ggml_opt_dataset_t dataset , 884ggml_opt_result_t result_train , 885ggml_opt_result_t result_eval , 886int64_t idata_split , 887ggml_opt_epoch_callback callback_train , 888ggml_opt_epoch_callback callback_eval ) { 889GGML_ASSERT (ggml_opt_static_graphs (opt_ctx )&& "ggml_opt_epoch requires static graphs" ); 890struct ggml_tensor * inputs = ggml_opt_inputs (opt_ctx ); 891struct ggml_tensor * labels = ggml_opt_labels (opt_ctx ); 892struct ggml_tensor * data = ggml_opt_dataset_data (dataset ); 893GGML_ASSERT (data -> ne [0 ]== inputs -> ne [0 ]); 894 895const int64_t ndata = data -> ne [1 ]; 896const int64_t ndata_batch = inputs -> ne [1 ]; 897 898GGML_ASSERT (data -> ne [1 ] %inputs -> ne [1 ]== 0 ); 899const int64_t nbatches = ndata /ndata_batch ; 900 901idata_split = idata_split < 0 ?ndata :idata_split ; 902GGML_ASSERT (idata_split %ndata_batch == 0 ); 903const int64_t ibatch_split = idata_split /ndata_batch ; 904 905int64_t ibatch = 0 ; 906int64_t t_loop_start = ggml_time_us (); 907for (;ibatch < ibatch_split ;++ ibatch ) { 908ggml_opt_alloc (opt_ctx ,/*backward =*/ true); 909ggml_opt_dataset_get_batch (dataset ,inputs ,labels ,ibatch ); 910ggml_opt_eval (opt_ctx ,result_train ); 911if (callback_train ) { 912callback_train (true,opt_ctx ,dataset ,result_train ,ibatch + 1 ,ibatch_split ,t_loop_start ); 913 } 914 } 915t_loop_start = ggml_time_us (); 916for (;ibatch < nbatches ;++ ibatch ) { 917ggml_opt_alloc (opt_ctx ,/*backward =*/ false); 918ggml_opt_dataset_get_batch (dataset ,inputs ,labels ,ibatch ); 919ggml_opt_eval (opt_ctx ,result_eval ); 920if (callback_eval ) { 921callback_eval (false,opt_ctx ,dataset ,result_eval ,ibatch + 1 - ibatch_split ,nbatches - ibatch_split ,t_loop_start ); 922 } 923 } 924} 925 926void ggml_opt_epoch_callback_progress_bar ( 927bool train , 928ggml_opt_context_t opt_ctx , 929ggml_opt_dataset_t dataset , 930ggml_opt_result_t result , 931int64_t ibatch , 932int64_t ibatch_max , 933int64_t t_start_us ) { 934fprintf (stderr ,"%s[" ,train ?"train: " :"val: " ); 935 936// The progress bar consists of partially filled blocks, unicode has 8 separate fill levels. 937constexpr int64_t bar_length = 8 ; 938const int64_t ibatch8 = 8 * ibatch ; 939for (int64_t j = 0 ;j < bar_length ;++ j ) { 940if (ibatch_max * (8 * j + 8 ) /bar_length < ibatch8 ) { 941fprintf (stderr ,"\u2588" );// full block 942 }else if (ibatch_max * (8 * j + 7 ) /bar_length < ibatch8 ) { 943fprintf (stderr ,"\u2589" );// 7/8 filled 944 }else if (ibatch_max * (8 * j + 6 ) /bar_length < ibatch8 ) { 945fprintf (stderr ,"\u258A" );// 6/8 filled 946 }else if (ibatch_max * (8 * j + 5 ) /bar_length < ibatch8 ) { 947fprintf (stderr ,"\u258B" );// 5/8 filled 948 }else if (ibatch_max * (8 * j + 4 ) /bar_length < ibatch8 ) { 949fprintf (stderr ,"\u258C" );// 4/8 filled 950 }else if (ibatch_max * (8 * j + 3 ) /bar_length < ibatch8 ) { 951fprintf (stderr ,"\u258D" );// 3/8 filled 952 }else if (ibatch_max * (8 * j + 2 ) /bar_length < ibatch8 ) { 953fprintf (stderr ,"\u258E" );// 2/8 filled 954 }else if (ibatch_max * (8 * j + 1 ) /bar_length < ibatch8 ) { 955fprintf (stderr ,"\u258F" );// 1/8 filled 956 }else { 957fprintf (stderr ," " ); 958 } 959 } 960 961const int64_t batch_size = ggml_opt_inputs (opt_ctx )-> ne [1 ]; 962const int64_t idata = ibatch * batch_size ; 963const int64_t idata_max = ibatch_max * batch_size ; 964 965double loss ; 966double loss_unc ; 967ggml_opt_result_loss (result ,& loss ,& loss_unc ); 968 969double accuracy ; 970double accuracy_unc ; 971ggml_opt_result_accuracy (result ,& accuracy ,& accuracy_unc ); 972 973const int64_t t_ibatch_us = ggml_time_us ()- t_start_us ; 974int64_t t_ibatch_s = t_ibatch_us /1000000 ; 975const int64_t t_ibatch_h = t_ibatch_s /3600 ; 976t_ibatch_s -= t_ibatch_h * 3600 ; 977const int64_t t_ibatch_m = t_ibatch_s /60 ; 978t_ibatch_s -= t_ibatch_m * 60 ; 979 980const int64_t t_eta_us = t_ibatch_us * (ibatch_max - ibatch )/ibatch ; 981int64_t t_eta_s = t_eta_us /1000000 ; 982const int64_t t_eta_h = t_eta_s /3600 ; 983t_eta_s -= t_eta_h * 3600 ; 984const int64_t t_eta_m = t_eta_s /60 ; 985t_eta_s -= t_eta_m * 60 ; 986 987fprintf (stderr ,"] data=%07" PRId64 "/%07" PRId64 " loss=%.5lf±%.5lf acc=%.2lf±%.2lf%% " 988"t=%02" PRId64 ":%02" PRId64 ":%02" PRId64 " ETA=%02" PRId64 ":%02" PRId64 ":%02" PRId64 " \r" , 989idata ,idata_max ,loss ,loss_unc ,100.0 * accuracy ,100.0 * accuracy_unc , 990t_ibatch_h ,t_ibatch_m ,t_ibatch_s ,t_eta_h ,t_eta_m ,t_eta_s ); 991if (ibatch == ibatch_max ) { 992fprintf (stderr ,"\n" ); 993 } 994fflush (stderr ); 995 996GGML_UNUSED (dataset ); 997} 998 999void ggml_opt_fit ( 1000ggml_backend_sched_t backend_sched , 1001ggml_context * ctx_compute , 1002ggml_tensor * inputs , 1003ggml_tensor * outputs , 1004ggml_opt_dataset_t dataset , 1005enum ggml_opt_loss_type loss_type , 1006enum ggml_opt_optimizer_type optimizer , 1007ggml_opt_get_optimizer_params get_opt_pars , 1008int64_t nepoch , 1009int64_t nbatch_logical , 1010float val_split , 1011bool silent ) { 1012ggml_time_init (); 1013const int64_t t_start_us = ggml_time_us (); 1014 1015const int64_t ndata = ggml_opt_dataset_data (dataset )-> ne [1 ]; 1016const int64_t nbatch_physical = inputs -> ne [1 ]; 1017GGML_ASSERT (ndata %nbatch_logical == 0 ); 1018GGML_ASSERT (nbatch_logical %nbatch_physical == 0 ); 1019 1020const int64_t opt_period = nbatch_logical /nbatch_physical ; 1021const int64_t nbatches_logical = ndata /nbatch_logical ; 1022 1023GGML_ASSERT (val_split >=0.0f ); 1024GGML_ASSERT (val_split < 1.0f ); 1025const int64_t ibatch_split = int64_t (((1.0f - val_split )* nbatches_logical ))* opt_period ;// train <-> val split index (physical) 1026const int64_t idata_split = ibatch_split * nbatch_physical ; 1027 1028int64_t epoch = 1 ; 1029 1030ggml_opt_params params = ggml_opt_default_params (backend_sched ,loss_type ); 1031params .ctx_compute = ctx_compute ; 1032params .inputs = inputs ; 1033params .outputs = outputs ; 1034params .opt_period = opt_period ; 1035params .get_opt_pars = get_opt_pars ; 1036params .get_opt_pars_ud = & epoch ; 1037params .optimizer = optimizer ; 1038ggml_opt_context_t opt_ctx = ggml_opt_init (params ); 1039 1040// Shuffling the data is generally useful but there is only a point if not all data is used in a single batch. 1041if (nbatch_logical < ndata ) { 1042ggml_opt_dataset_shuffle (opt_ctx ,dataset ,-1 );// Shuffle all data (train + validation). 1043 } 1044 1045ggml_opt_result_t result_train = ggml_opt_result_init (); 1046ggml_opt_result_t result_val = ggml_opt_result_init (); 1047 1048ggml_opt_epoch_callback epoch_callback = silent ?nullptr :ggml_opt_epoch_callback_progress_bar ; 1049 1050for (;epoch <=nepoch ;++ epoch ) { 1051if (nbatch_logical < idata_split ) { 1052ggml_opt_dataset_shuffle (opt_ctx ,dataset ,idata_split ); 1053 } 1054 1055ggml_opt_result_reset (result_train ); 1056ggml_opt_result_reset (result_val ); 1057 1058if (!silent ) { 1059fprintf (stderr ,"%s: epoch %04" PRId64 "/%04" PRId64 ":\n" ,__func__ ,epoch ,nepoch ); 1060 } 1061ggml_opt_epoch (opt_ctx ,dataset ,result_train ,result_val ,idata_split ,epoch_callback ,epoch_callback ); 1062if (!silent ) { 1063fprintf (stderr ,"\n" ); 1064 } 1065 } 1066 1067if (!silent ) { 1068int64_t t_total_s = (ggml_time_us ()- t_start_us ) /1000000 ; 1069const int64_t t_total_h = t_total_s /3600 ; 1070t_total_s -= t_total_h * 3600 ; 1071const int64_t t_total_m = t_total_s /60 ; 1072t_total_s -= t_total_m * 60 ; 1073fprintf (stderr ,"%s: training took %02" PRId64 ":%02" PRId64 ":%02" PRId64 "\n" ,__func__ ,t_total_h ,t_total_m ,t_total_s ); 1074 } 1075 1076ggml_opt_free (opt_ctx ); 1077ggml_opt_result_free (result_train ); 1078ggml_opt_result_free (result_val ); 1079} 1080 1081enum ggml_opt_optimizer_type ggml_opt_context_optimizer_type (ggml_opt_context_t c ) { 1082return c -> optimizer ; 1083} 1084 1085GGML_API const char * ggml_opt_optimizer_name (enum ggml_opt_optimizer_type o ) { 1086switch (o ) { 1087case GGML_OPT_OPTIMIZER_TYPE_ADAMW : 1088return "adamw" ; 1089case GGML_OPT_OPTIMIZER_TYPE_SGD : 1090return "sgd" ; 1091default : 1092return "undefined" ; 1093 }; 1094}