@@ -209,9 +209,9 @@ struct tensor_metadata {
209209// dequantization
210210//
211211
212- static void llama_tensor_dequantize_impl (
212+ static void llama_tensor_dequantize_chunk_impl (
213213 ggml_tensor * tensor, std::vector<no_init<float >> & output, std::vector<std::thread> & workers,
214- const size_t nelements, const int nthread
214+ const int64_t start, const size_t nelements, const int nthread
215215) {
216216 if (output.size () < nelements) {
217217 output.resize (nelements);
@@ -228,19 +228,6 @@ static void llama_tensor_dequantize_impl(
228228 throw std::runtime_error (format (" cannot dequantize/convert tensor type %s" , ggml_type_name (tensor->type )));
229229 }
230230
231- if (nthread < 2 ) {
232- if (tensor->type == GGML_TYPE_F16 ) {
233- ggml_fp16_to_fp32_row ((ggml_fp16_t *)tensor->data , f32_output, nelements);
234- } else if (tensor->type == GGML_TYPE_BF16 ) {
235- ggml_bf16_to_fp32_row ((ggml_bf16_t *)tensor->data , f32_output, nelements);
236- } else if (ggml_is_quantized (tensor->type )) {
237- qtype->to_float (tensor->data , f32_output, nelements);
238- } else {
239- GGML_ABORT (" fatal error" ); // unreachable
240- }
241- return ;
242- }
243-
244231 size_t block_size;
245232 if (tensor->type == GGML_TYPE_F16 ||
246233 tensor->type == GGML_TYPE_BF16 ) {
@@ -249,9 +236,27 @@ static void llama_tensor_dequantize_impl(
249236 block_size = (size_t )ggml_blck_size (tensor->type );
250237 }
251238
239+ GGML_ASSERT (start >= 0 );
240+ GGML_ASSERT ((size_t ) start % block_size == 0 );
241+ GGML_ASSERT (nelements % block_size == 0 );
242+
252243 size_t block_size_bytes = ggml_type_size (tensor->type );
244+ const size_t input_offset = ((size_t ) start / block_size) * block_size_bytes;
245+ uint8_t * input_data = (uint8_t *) tensor->data + input_offset;
246+
247+ if (nthread < 2 ) {
248+ if (tensor->type == GGML_TYPE_F16 ) {
249+ ggml_fp16_to_fp32_row ((ggml_fp16_t *) input_data, f32_output, nelements);
250+ } else if (tensor->type == GGML_TYPE_BF16 ) {
251+ ggml_bf16_to_fp32_row ((ggml_bf16_t *) input_data, f32_output, nelements);
252+ } else if (ggml_is_quantized (tensor->type )) {
253+ qtype->to_float (input_data, f32_output, nelements);
254+ } else {
255+ GGML_ABORT (" fatal error" ); // unreachable
256+ }
257+ return ;
258+ }
253259
254- GGML_ASSERT (nelements % block_size == 0 );
255260 size_t nblocks = nelements / block_size;
256261 size_t blocks_per_thread = nblocks / nthread;
257262 size_t spare_blocks = nblocks - (blocks_per_thread * nthread); // if blocks aren't divisible by thread count
@@ -264,7 +269,7 @@ static void llama_tensor_dequantize_impl(
264269 size_t thr_elems = thr_blocks * block_size; // number of elements for this thread
265270 size_t thr_block_bytes = thr_blocks * block_size_bytes; // number of input bytes for this thread
266271
267- auto compute = [qtype] (ggml_type typ, uint8_t * inbuf, float * outbuf, int nels) {
272+ auto compute = [qtype] (ggml_type typ, uint8_t * inbuf, float * outbuf, int64_t nels) {
268273 if (typ == GGML_TYPE_F16 ) {
269274 ggml_fp16_to_fp32_row ((ggml_fp16_t *)inbuf, outbuf, nels);
270275 } else if (typ == GGML_TYPE_BF16 ) {
@@ -273,14 +278,21 @@ static void llama_tensor_dequantize_impl(
273278 qtype->to_float (inbuf, outbuf, nels);
274279 }
275280 };
276- workers.emplace_back (compute, tensor->type , ( uint8_t *) tensor-> data + in_buff_offs, f32_output + out_buff_offs, thr_elems);
281+ workers.emplace_back (compute, tensor->type , input_data + in_buff_offs, f32_output + out_buff_offs, thr_elems);
277282 in_buff_offs += thr_block_bytes;
278283 out_buff_offs += thr_elems;
279284 }
280285 for (auto & w : workers) { w.join (); }
281286 workers.clear ();
282287}
283288
289+ static void llama_tensor_dequantize_impl (
290+ ggml_tensor * tensor, std::vector<no_init<float >> & output, std::vector<std::thread> & workers,
291+ const size_t nelements, const int nthread
292+ ) {
293+ llama_tensor_dequantize_chunk_impl (tensor, output, workers, 0 , nelements, nthread);
294+ }
295+
284296//
285297// do we allow this tensor to be quantized?
286298//
@@ -1208,43 +1220,70 @@ static void llama_model_quantize_impl(const std::string & fname_inp, const std::
12081220 throw std::runtime_error (format (" Missing importance matrix for tensor %s in a very low-bit quantization" , tensor->name ));
12091221 }
12101222
1211- float * f32_data;
1212-
1213- if (tensor->type == GGML_TYPE_F32 ) {
1214- f32_data = (float *) tensor->data ;
1215- } else if (ggml_is_quantized (tensor->type ) && !params->allow_requantize ) {
1216- throw std::runtime_error (format (" requantizing from type %s is disabled" , ggml_type_name (tensor->type )));
1217- } else {
1218- llama_tensor_dequantize_impl (tensor, f32_conv_buf, workers, nelements, nthread);
1219- f32_data = (float *) f32_conv_buf.data ();
1220- }
1221-
12221223 LLAMA_LOG_INFO (" converting to %s .. " , ggml_type_name (new_type));
12231224 fflush (stdout);
12241225
1225- if (work.size () < (size_t )nelements * 4 ) {
1226- work.resize (nelements * 4 ); // upper bound on size
1227- }
1228- new_data = work.data ();
1229-
12301226 const int64_t n_per_row = tensor->ne [0 ];
12311227 const int64_t nrows = tensor->ne [1 ];
1228+ const size_t row_size = ggml_row_size (new_type, n_per_row);
1229+ const size_t work_size = row_size * nrows * tensor->ne [2 ];
1230+
1231+ if (work.size () < work_size) {
1232+ work.resize (work_size);
1233+ }
1234+ new_data = work.data ();
12321235
12331236 static const int64_t min_chunk_size = 32 * 512 ;
12341237 const int64_t chunk_size = (n_per_row >= min_chunk_size ? n_per_row : n_per_row * ((min_chunk_size + n_per_row - 1 )/n_per_row));
12351238
12361239 const int64_t nelements_matrix = tensor->ne [0 ] * tensor->ne [1 ];
12371240 const int64_t nchunk = (nelements_matrix + chunk_size - 1 )/chunk_size;
12381241 const int64_t nthread_use = nthread > 1 ? std::max ((int64_t )1 , std::min ((int64_t )nthread, nchunk)) : 1 ;
1242+ const bool stream_source = tensor->type == GGML_TYPE_F16 || tensor->type == GGML_TYPE_BF16 ;
12391243
12401244 // quantize each expert separately since they have different importance matrices
12411245 new_size = 0 ;
1242- for (int64_t i03 = 0 ; i03 < tensor->ne [2 ]; ++i03) {
1243- const float * f32_data_03 = f32_data + i03 * nelements_matrix;
1244- void * new_data_03 = (char *)new_data + ggml_row_size (new_type, n_per_row) * i03 * nrows;
1245- const float * imatrix_03 = imatrix ? imatrix + i03 * n_per_row : nullptr ;
1246+ if (stream_source) {
1247+ static const int64_t stream_chunk_size = 32 * 1024 * 1024 ;
1248+ const int64_t rows_per_stream_chunk = std::max<int64_t >(1 , std::max (chunk_size, stream_chunk_size) / n_per_row);
12461249
1247- new_size += llama_tensor_quantize_impl (new_type, f32_data_03, new_data_03, chunk_size, nrows, n_per_row, imatrix_03, workers, nthread_use);
1250+ for (int64_t i03 = 0 ; i03 < tensor->ne [2 ]; ++i03) {
1251+ void * new_data_03 = (char *)new_data + row_size * i03 * nrows;
1252+ const float * imatrix_03 = imatrix ? imatrix + i03 * n_per_row : nullptr ;
1253+
1254+ for (int64_t first_row = 0 ; first_row < nrows; first_row += rows_per_stream_chunk) {
1255+ const int64_t this_nrow = std::min (nrows - first_row, rows_per_stream_chunk);
1256+ const int64_t start = i03 * nelements_matrix + first_row * n_per_row;
1257+ const size_t chunk_nelements = this_nrow * n_per_row;
1258+
1259+ llama_tensor_dequantize_chunk_impl (tensor, f32_conv_buf, workers, start, chunk_nelements, nthread);
1260+
1261+ void * new_data_chunk = (char *) new_data_03 + row_size * first_row;
1262+ const int64_t chunk_nchunk = (chunk_nelements + chunk_size - 1 ) / chunk_size;
1263+ const int64_t chunk_nthread = nthread > 1 ? std::max ((int64_t )1 , std::min ((int64_t )nthread, chunk_nchunk)) : 1 ;
1264+
1265+ new_size += llama_tensor_quantize_impl (new_type, (float *) f32_conv_buf.data (), new_data_chunk, chunk_size, this_nrow, n_per_row, imatrix_03, workers, chunk_nthread);
1266+ }
1267+ }
1268+ } else {
1269+ float * f32_data;
1270+
1271+ if (tensor->type == GGML_TYPE_F32 ) {
1272+ f32_data = (float *) tensor->data ;
1273+ } else if (ggml_is_quantized (tensor->type ) && !params->allow_requantize ) {
1274+ throw std::runtime_error (format (" requantizing from type %s is disabled" , ggml_type_name (tensor->type )));
1275+ } else {
1276+ llama_tensor_dequantize_impl (tensor, f32_conv_buf, workers, nelements, nthread);
1277+ f32_data = (float *) f32_conv_buf.data ();
1278+ }
1279+
1280+ for (int64_t i03 = 0 ; i03 < tensor->ne [2 ]; ++i03) {
1281+ const float * f32_data_03 = f32_data + i03 * nelements_matrix;
1282+ void * new_data_03 = (char *)new_data + row_size * i03 * nrows;
1283+ const float * imatrix_03 = imatrix ? imatrix + i03 * n_per_row : nullptr ;
1284+
1285+ new_size += llama_tensor_quantize_impl (new_type, f32_data_03, new_data_03, chunk_size, nrows, n_per_row, imatrix_03, workers, nthread_use);
1286+ }
12481287 }
12491288 LLAMA_LOG_INFO (" size = %8.2f MiB -> %8.2f MiB\n " , tensor_size/1024.0 /1024.0 , new_size/1024.0 /1024.0 );
12501289 }
0 commit comments