Module: ToyDriftGrad
- Defined in:
- lib/toy/train/toy_drift_grad.rb
Class Method Summary collapse
-
.emit_drift_event(sess, t, snap_mat, step, t_now) ⇒ Object
Emit one ‘drift` event for tensor t, comparing against snap_mat.
-
.emit_grad_event(sess, t, step, t_now) ⇒ Object
Emit one ‘grad` event for tensor t.
-
.params(sess) ⇒ Object
Walk session graph + leaves, return ordered array of (ptr, name) for every PARAM-flagged tensor (flags bit 4 set).
-
.snapshot_one(sess, t) ⇒ Object
Snapshot ONE param’s current values into a fresh Mat.
Class Method Details
.emit_drift_event(sess, t, snap_mat, step, t_now) ⇒ Object
Emit one ‘drift` event for tensor t, comparing against snap_mat. Single-pass cos + L2 loop over the f64 flats.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/toy/train/toy_drift_grad.rb', line 107 def self.emit_drift_event(sess, t, snap_mat, step, t_now) n = TinyNN.tnn_tensor_nelements(t) cur = Mat.new(1, n) TinyNN.tnn_download_to_f64_array(sess, t, cur.flat, n) dot = 0.0 sum_sq_s = 0.0 sum_sq_c = 0.0 sum_sq_diff = 0.0 i = 0 while i < n sv = snap_mat.flat[i] cv = cur.flat[i] dot = dot + sv * cv sum_sq_s = sum_sq_s + sv * sv sum_sq_c = sum_sq_c + cv * cv d = sv - cv sum_sq_diff = sum_sq_diff + d * d i = i + 1 end norm_s = sum_sq_s ** 0.5 norm_c = sum_sq_c ** 0.5 cos_to_init = 0.0 if norm_s > 0.0 && norm_c > 0.0 cos_to_init = dot / (norm_s * norm_c) end l2_to_init = sum_sq_diff ** 0.5 name = TinyNN.tnn_tensor_name(t) ev = SpinelKit::Json::Builder.new ev.add_str("kind", "drift") ev.add_str("phase", "train") ev.add_num("t", t_now) ev.add_num("step", step) ev.add_str("param", name) ev.add_num("cos_to_init", cos_to_init) ev.add_num("l2_to_init", l2_to_init) TinyNN.tnn_events_emit(ev.dump) end |
.emit_grad_event(sess, t, step, t_now) ⇒ Object
Emit one ‘grad` event for tensor t. Call after tnn_compute_backward but before the next step’s reset (so the grad tensor is still live).
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/toy/train/toy_drift_grad.rb', line 149 def self.emit_grad_event(sess, t, step, t_now) g = TinyNN.tnn_tensor_grad(sess, t) if g == nil || g == TinyNN.tnn_null_ptr return end n = TinyNN.tnn_tensor_nelements(g) TinyNN.tnn_download(sess, g) sum_sq = TinyNN.tnn_scratch_sum_sq_f32(sess, n) sum_abs = TinyNN.tnn_scratch_sum_abs_f32(sess, n) nan = TinyNN.tnn_scratch_nan_count_f32(sess, n) l2 = sum_sq ** 0.5 abs_mean = sum_abs / n.to_f ne0 = TinyNN.tnn_tensor_ne0(g) ne1 = TinyNN.tnn_tensor_ne1(g) name = TinyNN.tnn_tensor_name(t) ev = SpinelKit::Json::Builder.new ev.add_str("kind", "grad") ev.add_str("phase", "train") ev.add_num("t", t_now) ev.add_num("step", step) ev.add_str("param", name) ev.add_raw("shape", "[" + ne0.to_s + "," + ne1.to_s + "]") ev.add_num("l2", l2) ev.add_num("abs_mean", abs_mean) ev.add_num("nan_count", nan) TinyNN.tnn_events_emit(ev.dump) end |
.params(sess) ⇒ Object
Walk session graph + leaves, return ordered array of (ptr, name) for every PARAM-flagged tensor (flags bit 4 set). The flag is ‘ggml_set_param`-marked, so this exactly matches the params the training graph differentiates over.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/toy/train/toy_drift_grad.rb', line 43 def self.params(sess) ptrs = [TinyNN.tnn_null_ptr]; ptrs.pop seen = [TinyNN.tnn_null_ptr]; seen.pop # Collect every distinct tensor reachable from the graph: nodes + # their src dependencies. Filter to PARAM-flagged. n_nodes = TinyNN.tnn_graph_n_nodes(sess) i = 0 while i < n_nodes node = TinyNN.tnn_graph_node(sess, i) # The node itself seen.push(node) # Its srcs (leaves usually carry the PARAM flag) si = 0 while si < 10 src = TinyNN.tnn_tensor_src(node, si) if src == nil || src == TinyNN.tnn_null_ptr si = 10 else # Already seen? dup = false k = 0 while k < seen.length if seen[k] == src dup = true k = seen.length else k = k + 1 end end if !dup seen.push(src) end si = si + 1 end end i = i + 1 end # Filter by PARAM flag. i = 0 while i < seen.length t = seen[i] flags = TinyNN.tnn_tensor_flags(t) if (flags & 4) != 0 ptrs.push(t) end i = i + 1 end ptrs end |
.snapshot_one(sess, t) ⇒ Object
Snapshot ONE param’s current values into a fresh Mat. Caller keeps these in a main-scope Array<Mat> (a separate per-step Array would force Spinel to declare sp_Mat_ptr_array, which it can’t).
98 99 100 101 102 103 |
# File 'lib/toy/train/toy_drift_grad.rb', line 98 def self.snapshot_one(sess, t) n = TinyNN.tnn_tensor_nelements(t) m = Mat.new(1, n) TinyNN.tnn_download_to_f64_array(sess, t, m.flat, n) m end |