Skip to content

Commit e13df76

Browse files
committed
*.py: Convert all python scripts to use logging module
1 parent ff3ad88 commit e13df76

18 files changed

+388
-296
lines changed

convert-hf-to-gguf.py

Lines changed: 90 additions & 81 deletions
Large diffs are not rendered by default.

convert-llama-ggml-to-gguf.py

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python3
22
from __future__ import annotations
33

4+
import logging
45
import argparse
56
import os
67
import struct
@@ -14,6 +15,8 @@
1415
sys.path.insert(1, str(Path(__file__).parent / 'gguf-py'))
1516
import gguf
1617

18+
logger = logging.getLogger("ggml-to-gguf")
19+
1720

1821
class GGMLFormat(IntEnum):
1922
GGML = 0
@@ -125,7 +128,7 @@ def load(self, data, offset):
125128
self.start_offset = offset
126129
self.len_bytes = n_bytes
127130
offset += n_bytes
128-
# print(n_dims, name_len, dtype, self.dims, self.name, pad)
131+
# logger.info(n_dims, name_len, dtype, self.dims, self.name, pad)
129132
return offset - orig_offset
130133

131134

@@ -175,7 +178,7 @@ def load(self, data, offset):
175178
offset += self.validate_header(data, offset)
176179
hp = Hyperparameters()
177180
offset += hp.load(data, offset)
178-
print(f'* File format: {self.file_format.name}v{self.format_version} with ftype {hp.ftype.name}')
181+
logger.info(f'* File format: {self.file_format.name}v{self.format_version} with ftype {hp.ftype.name}')
179182
self.validate_conversion(hp.ftype)
180183
vocab = Vocab(load_scores = self.file_format > GGMLFormat.GGML)
181184
offset += vocab.load(data, offset, hp.n_vocab)
@@ -215,12 +218,12 @@ def __init__(self, ggml_model, data, cfg, params_override = None, vocab_override
215218
if float(hp.n_head) / float(x) == gqa:
216219
n_kv_head = x
217220
assert n_kv_head is not None, "Couldn't determine n_kv_head from GQA param"
218-
print(f'- Guessed n_kv_head = {n_kv_head} based on GQA {cfg.gqa}')
221+
logger.info(f'- Guessed n_kv_head = {n_kv_head} based on GQA {cfg.gqa}')
219222
self.n_kv_head = n_kv_head
220223
self.name_map = gguf.get_tensor_name_map(gguf.MODEL_ARCH.LLAMA, ggml_model.hyperparameters.n_layer)
221224

222225
def save(self):
223-
print('* Preparing to save GGUF file')
226+
logger.info('* Preparing to save GGUF file')
224227
gguf_writer = gguf.GGUFWriter(
225228
self.cfg.output,
226229
gguf.MODEL_ARCH_NAMES[gguf.MODEL_ARCH.LLAMA],
@@ -230,11 +233,11 @@ def save(self):
230233
if self.special_vocab is not None:
231234
self.special_vocab.add_to_gguf(gguf_writer)
232235
self.add_tensors(gguf_writer)
233-
print(" gguf: write header")
236+
logger.info(" gguf: write header")
234237
gguf_writer.write_header_to_file()
235-
print(" gguf: write metadata")
238+
logger.info(" gguf: write metadata")
236239
gguf_writer.write_kv_data_to_file()
237-
print(" gguf: write tensors")
240+
logger.info(" gguf: write tensors")
238241
gguf_writer.write_tensors_to_file()
239242
gguf_writer.close()
240243

@@ -250,7 +253,7 @@ def add_params(self, gguf_writer):
250253
name = cfg.name if cfg.name is not None else cfg.input.name
251254
except UnicodeDecodeError:
252255
name = None
253-
print('* Adding model parameters and KV items')
256+
logger.info('* Adding model parameters and KV items')
254257
if name is not None:
255258
gguf_writer.add_name(name)
256259
gguf_writer.add_description(desc)
@@ -286,7 +289,7 @@ def add_vocab(self, gguf_writer):
286289
toktypes = []
287290
if self.vocab_override is not None:
288291
vo = self.vocab_override
289-
print('* Adding vocab item(s)')
292+
logger.info('* Adding vocab item(s)')
290293
for (idx, (vbytes, score, ttype)) in enumerate(vo.all_tokens()):
291294
tokens.append(vbytes)
292295
scores.append(score)
@@ -298,7 +301,7 @@ def add_vocab(self, gguf_writer):
298301
if len(toktypes) > 0:
299302
gguf_writer.add_token_types(toktypes)
300303
return
301-
print(f'* Adding {hp.n_vocab} vocab item(s)')
304+
logger.info(f'* Adding {hp.n_vocab} vocab item(s)')
302305
assert len(self.model.vocab.items) >= 3, 'Cannot handle unexpectedly short model vocab'
303306
for (tokid, (vbytes, vscore)) in enumerate(self.model.vocab.items):
304307
tt = 1 # Normal
@@ -333,7 +336,7 @@ def add_vocab(self, gguf_writer):
333336
def add_tensors(self, gguf_writer):
334337
tensor_map = self.name_map
335338
data = self.data
336-
print(f'* Adding {len(self.model.tensors)} tensor(s)')
339+
logger.info(f'* Adding {len(self.model.tensors)} tensor(s)')
337340
for tensor in self.model.tensors:
338341
name = str(tensor.name, 'UTF-8')
339342
mapped_name = tensor_map.get_name(name, try_suffixes = (".weight", ".bias"))
@@ -343,7 +346,7 @@ def add_tensors(self, gguf_writer):
343346
temp = tempdims[1]
344347
tempdims[1] = tempdims[0]
345348
tempdims[0] = temp
346-
# print(f'+ {tensor.name} | {mapped_name} {tensor.dims} :: {tempdims}')
349+
# logger.info(f'+ {tensor.name} | {mapped_name} {tensor.dims} :: {tempdims}')
347350
gguf_writer.add_tensor(
348351
mapped_name,
349352
data[tensor.start_offset:tensor.start_offset + tensor.len_bytes],
@@ -400,41 +403,46 @@ def handle_args():
400403
help="directory containing tokenizer.model, if separate from model file - only meaningful with --model-metadata-dir")
401404
parser.add_argument("--vocabtype", default="spm,hfft",
402405
help="vocab format - only meaningful with --model-metadata-dir and/or --vocab-dir (default: spm,hfft)")
406+
parser.add_argument("--verbose", action="store_true", help="increase output verbosity")
403407
return parser.parse_args()
404408

405409

406410
def main():
407411
cfg = handle_args()
408-
print(f'* Using config: {cfg}')
409-
print('\n=== WARNING === Be aware that this conversion script is best-effort. Use a native GGUF model if possible. === WARNING ===\n')
412+
if cfg.verbose:
413+
logging.basicConfig(level=logging.DEBUG)
414+
else:
415+
logging.basicConfig(level=logging.INFO)
416+
logger.info(f'* Using config: {cfg}')
417+
logger.warning('=== WARNING === Be aware that this conversion script is best-effort. Use a native GGUF model if possible. === WARNING ===')
410418
if cfg.model_metadata_dir is None and (cfg.gqa == 1 or cfg.eps == '5.0e-06'):
411-
print('- Note: If converting LLaMA2, specifying "--eps 1e-5" is required. 70B models also need "--gqa 8".')
419+
logger.info('- Note: If converting LLaMA2, specifying "--eps 1e-5" is required. 70B models also need "--gqa 8".')
412420
data = np.memmap(cfg.input, mode = 'r')
413421
model = GGMLModel()
414-
print('* Scanning GGML input file')
422+
logger.info('* Scanning GGML input file')
415423
offset = model.load(data, 0) # noqa
416-
print(f'* GGML model hyperparameters: {model.hyperparameters}')
424+
logger.info(f'* GGML model hyperparameters: {model.hyperparameters}')
417425
vocab_override = None
418426
params_override = None
419427
special_vocab = None
420428
if cfg.model_metadata_dir is not None:
421429
(params_override, vocab_override, special_vocab) = handle_metadata(cfg, model.hyperparameters)
422-
print('!! Note: When overriding params the --gqa, --eps and --context-length options are ignored.')
423-
print(f'* Overriding params: {params_override}')
424-
print(f'* Overriding vocab: {vocab_override}')
425-
print(f'* Special vocab: {special_vocab}')
430+
logger.info('!! Note: When overriding params the --gqa, --eps and --context-length options are ignored.')
431+
logger.info(f'* Overriding params: {params_override}')
432+
logger.info(f'* Overriding vocab: {vocab_override}')
433+
logger.info(f'* Special vocab: {special_vocab}')
426434
else:
427-
print('\n=== WARNING === Special tokens may not be converted correctly. Use --model-metadata-dir if possible === WARNING ===\n')
435+
logger.warning('\n=== WARNING === Special tokens may not be converted correctly. Use --model-metadata-dir if possible === WARNING ===\n')
428436
if model.file_format == GGMLFormat.GGML:
429-
print('! This is a very old GGML file that does not contain vocab scores. Strongly recommend using model metadata!')
437+
logger.info('! This is a very old GGML file that does not contain vocab scores. Strongly recommend using model metadata!')
430438
converter = GGMLToGGUF(
431439
model, data, cfg,
432440
params_override = params_override,
433441
vocab_override = vocab_override,
434442
special_vocab = special_vocab
435443
)
436444
converter.save()
437-
print(f'* Successful completion. Output saved to: {cfg.output}')
445+
logger.info(f'* Successful completion. Output saved to: {cfg.output}')
438446

439447

440448
if __name__ == '__main__':

convert-lora-to-ggml.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python3
22
from __future__ import annotations
33

4+
import logging
45
import json
56
import os
67
import struct
@@ -15,6 +16,8 @@
1516
sys.path.insert(1, str(Path(__file__).parent / 'gguf-py' / 'gguf'))
1617
import gguf
1718

19+
logger = logging.getLogger("lora-to-gguf")
20+
1821
NUMPY_TYPE_TO_FTYPE: dict[str, int] = {"float32": 0, "float16": 1}
1922

2023

@@ -48,11 +51,9 @@ def write_tensor_header(fout: BinaryIO, name: str, shape: Sequence[int], data_ty
4851

4952
if __name__ == '__main__':
5053
if len(sys.argv) < 2:
51-
print(f"Usage: python {sys.argv[0]} <path> [arch]")
52-
print(
53-
"Path must contain HuggingFace PEFT LoRA files 'adapter_config.json' and 'adapter_model.bin'"
54-
)
55-
print(f"Arch must be one of {list(gguf.MODEL_ARCH_NAMES.values())} (default: llama)")
54+
logger.info(f"Usage: python {sys.argv[0]} <path> [arch]")
55+
logger.info("Path must contain HuggingFace PEFT LoRA files 'adapter_config.json' and 'adapter_model.bin'")
56+
logger.info(f"Arch must be one of {list(gguf.MODEL_ARCH_NAMES.values())} (default: llama)")
5657
sys.exit(1)
5758

5859
input_json = os.path.join(sys.argv[1], "adapter_config.json")
@@ -70,7 +71,7 @@ def write_tensor_header(fout: BinaryIO, name: str, shape: Sequence[int], data_ty
7071
arch_name = sys.argv[2] if len(sys.argv) == 3 else "llama"
7172

7273
if arch_name not in gguf.MODEL_ARCH_NAMES.values():
73-
print(f"Error: unsupported architecture {arch_name}")
74+
logger.error(f"Error: unsupported architecture {arch_name}")
7475
sys.exit(1)
7576

7677
arch = list(gguf.MODEL_ARCH_NAMES.keys())[list(gguf.MODEL_ARCH_NAMES.values()).index(arch_name)]
@@ -80,21 +81,21 @@ def write_tensor_header(fout: BinaryIO, name: str, shape: Sequence[int], data_ty
8081
params = json.load(f)
8182

8283
if params["peft_type"] != "LORA":
83-
print(f"Error: unsupported adapter type {params['peft_type']}, expected LORA")
84+
logger.error(f"Error: unsupported adapter type {params['peft_type']}, expected LORA")
8485
sys.exit(1)
8586

8687
if params["fan_in_fan_out"] is True:
87-
print("Error: param fan_in_fan_out is not supported")
88+
logger.error("Error: param fan_in_fan_out is not supported")
8889
sys.exit(1)
8990

9091
if params["bias"] is not None and params["bias"] != "none":
91-
print("Error: param bias is not supported")
92+
logger.error("Error: param bias is not supported")
9293
sys.exit(1)
9394

9495
# TODO: these seem to be layers that have been trained but without lora.
9596
# doesn't seem widely used but eventually should be supported
9697
if params["modules_to_save"] is not None and len(params["modules_to_save"]) > 0:
97-
print("Error: param modules_to_save is not supported")
98+
logger.error("Error: param modules_to_save is not supported")
9899
sys.exit(1)
99100

100101
with open(output_path, "wb") as fout:
@@ -125,13 +126,13 @@ def write_tensor_header(fout: BinaryIO, name: str, shape: Sequence[int], data_ty
125126
suffix = k[-len(lora_suffixes[0]):]
126127
k = k[: -len(lora_suffixes[0])]
127128
else:
128-
print(f"Error: unrecognized tensor name {orig_k}")
129+
logger.error(f"Error: unrecognized tensor name {orig_k}")
129130
sys.exit(1)
130131

131132
tname = name_map.get_name(k)
132133
if tname is None:
133-
print(f"Error: could not map tensor name {orig_k}")
134-
print(" Note: the arch parameter must be specified if the model is not llama")
134+
logger.error(f"Error: could not map tensor name {orig_k}")
135+
logger.error(" Note: the arch parameter must be specified if the model is not llama")
135136
sys.exit(1)
136137

137138
if suffix == ".lora_A.weight":
@@ -141,8 +142,8 @@ def write_tensor_header(fout: BinaryIO, name: str, shape: Sequence[int], data_ty
141142
else:
142143
assert False
143144

144-
print(f"{k} => {tname} {t.shape} {t.dtype} {t.nbytes/1024/1024:.2f}MB")
145+
logger.info(f"{k} => {tname} {t.shape} {t.dtype} {t.nbytes/1024/1024:.2f}MB")
145146
write_tensor_header(fout, tname, t.shape, t.dtype)
146147
t.tofile(fout)
147148

148-
print(f"Converted {input_json} and {input_model} to {output_path}")
149+
logger.info(f"Converted {input_json} and {input_model} to {output_path}")

convert-persimmon-to-gguf.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python3
22
from __future__ import annotations
33

4+
import logging
45
import argparse
56
import os
67
import sys
@@ -14,6 +15,8 @@
1415
sys.path.insert(1, str(Path(__file__).parent / 'gguf-py'))
1516
import gguf
1617

18+
logger = logging.getLogger("persimmon-to-gguf")
19+
1720

1821
def _flatten_dict(dct, tensors, prefix=None):
1922
assert isinstance(dct, dict)
@@ -30,9 +33,9 @@ def _flatten_dict(dct, tensors, prefix=None):
3033

3134
def _get_sentencepiece_tokenizer_info(dir_model: Path):
3235
tokenizer_path = dir_model / 'adept_vocab.model'
33-
print('gguf: getting sentencepiece tokenizer from', tokenizer_path)
36+
logger.info('getting sentencepiece tokenizer from', tokenizer_path)
3437
tokenizer = SentencePieceProcessor(str(tokenizer_path))
35-
print('gguf: adding tokens')
38+
logger.info('adding tokens')
3639
tokens: list[bytes] = []
3740
scores: list[float] = []
3841
toktypes: list[int] = []
@@ -67,8 +70,13 @@ def main():
6770
parser.add_argument("--outfile", type=Path, help="path to write to; default: based on input")
6871
parser.add_argument("--ckpt-path", type=Path, help="path to persimmon checkpoint .pt file")
6972
parser.add_argument("--model-dir", type=Path, help="directory containing model e.g. 8b_chat_model_release")
70-
parser.add_argument("--adept-inference-dir", type=str, help="path to adept-inference code directory")
73+
parser.add_argument("--adept-inference-dir", type=str, help="path to adept-inference code directory")
74+
parser.add_argument("--verbose", action="store_true", help="increase output verbosity")
7175
args = parser.parse_args()
76+
if args.verbose:
77+
logging.basicConfig(level=logging.DEBUG)
78+
else:
79+
logging.basicConfig(level=logging.INFO)
7280
sys.path.append(str(args.adept_inference_dir))
7381
persimmon_model = torch.load(args.ckpt_path)
7482
hparams = persimmon_model['args']
@@ -106,7 +114,7 @@ def main():
106114
gguf_writer.add_eos_token_id(71013)
107115

108116
tensor_map = gguf.get_tensor_name_map(arch, block_count)
109-
print(tensor_map)
117+
logger.info(tensor_map)
110118
for name in tensors.keys():
111119
data_torch = tensors[name]
112120
if name.endswith(".self_attention.rotary_emb.inv_freq"):
@@ -116,22 +124,21 @@ def main():
116124
data = data_torch.to(torch.float32).squeeze().numpy()
117125
new_name = tensor_map.get_name(name, try_suffixes = (".weight", ".bias"))
118126
if new_name is None:
119-
print("Can not map tensor '" + name + "'")
127+
logger.error(f"Can not map tensor '{name}'")
120128
sys.exit()
121129
n_dims = len(data.shape)
122-
print(new_name + ", n_dims = " + str(n_dims) + ", " + str(old_dtype) + " --> " + str(data.dtype))
130+
logger.debug(f"{new_name}, n_dims = {str(n_dims)}, {str(old_dtype)} --> {str(data.dtype)}")
123131
gguf_writer.add_tensor(new_name, data)
124-
print("gguf: write header")
132+
logger.info("gguf: write header")
125133
gguf_writer.write_header_to_file()
126-
print("gguf: write metadata")
134+
logger.info("gguf: write metadata")
127135
gguf_writer.write_kv_data_to_file()
128-
print("gguf: write tensors")
136+
logger.info("gguf: write tensors")
129137
gguf_writer.write_tensors_to_file()
130138

131139
gguf_writer.close()
132140

133-
print(f"gguf: model successfully exported to '{args.outfile}'")
134-
print("")
141+
logger.info(f"gguf: model successfully exported to '{args.outfile}'")
135142

136143

137144
if __name__ == '__main__':

convert.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,11 +1442,11 @@ def default_outfile(model_paths: list[Path], file_type: GGMLFileType) -> Path:
14421442

14431443

14441444
def do_dump_model(model_plus: ModelPlus) -> None:
1445-
print(f"model_plus.paths = {model_plus.paths!r}")
1446-
print(f"model_plus.format = {model_plus.format!r}")
1447-
print(f"model_plus.vocab = {model_plus.vocab!r}")
1445+
print(f"model_plus.paths = {model_plus.paths!r}") # noqa: NP100
1446+
print(f"model_plus.format = {model_plus.format!r}") # noqa: NP100
1447+
print(f"model_plus.vocab = {model_plus.vocab!r}") # noqa: NP100
14481448
for name, lazy_tensor in model_plus.model.items():
1449-
print(f"{name}: shape={lazy_tensor.shape} type={lazy_tensor.data_type}; {lazy_tensor.description}")
1449+
print(f"{name}: shape={lazy_tensor.shape} type={lazy_tensor.data_type}; {lazy_tensor.description}") # noqa: NP100
14501450

14511451

14521452
def main(args_in: list[str] | None = None) -> None:

0 commit comments

Comments
 (0)