Views
No views yet
openSUSE:Factory with the diffs of the spec file and every files which looks like
a changelog.pip install ctranslate2 transformers1import ctranslate2
2from transformers import AutoTokenizer
3from huggingface_hub import snapshot_download
4
5# Choose quantization variant:
6# - float32: Full precision, no quality loss
7# - float16: 50% smaller, GPU only
8# - int8_float16: 75% smaller, GPU only
9# - int8: 75% smaller, CPU/GPU compatible (Recommended)
10
11repo_id = "mslacken/t5-finetune-changelog"
12model_size = "large" # Recommended
13quantization = "int8" # Recommended: int8 for CPU/GPU compatibility
14
15# Download CTranslate2 model from HuggingFace
16print("Downloading model...")
17model_dir = snapshot_download(
18 repo_id=repo_id,
19 allow_patterns=f"ct2_models/t5-{model_size}-ct2-{quantization}/*"
20)
21ct2_model_path = f"{model_dir}/ct2_models/t5-{model_size}-ct2-{quantization}"
22
23# Load CTranslate2 model
24translator = ctranslate2.Translator(ct2_model_path, device="cpu") # or "cuda"
25
26# Load tokenizer from the fine-tuned model
27subfolder = f"t5-{model_size}"
28tokenizer = AutoTokenizer.from_pretrained(repo_id, subfolder=subfolder)
29
30# Helper function to decode while preserving newlines
31def decode_changelog(tokens):
32 import re
33 decoded = tokenizer.decode(tokenizer.convert_tokens_to_ids(tokens), skip_special_tokens=False)
34 decoded = decoded.replace(tokenizer.pad_token or "<pad>", "")
35 decoded = decoded.replace(tokenizer.eos_token or "</s>", "")
36 decoded = re.sub(r"<extra_id_\d+>", "", decoded)
37 return decoded.strip()
38
39# Example input
40input_text = """create structured changelog for package warewulf4 from 4.2.0 to 4.3.0rc2:
41changelog:
42# Changelog
43All notable changes to this project will be documented in this file.
44The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
45and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
46## [Unreleased]
47### Changed
48- Provision interface is not tied to 'eth0' any more. The provision interface must be named
49'default' now. The file 'nodes.yaml' must be changed accordingly.
50- Creating of '/etc/exports' can now be disabled, so that wwctl configure -a wont overwrite
51a existing '/etc/exports'.
52- All configurations files for the host (/etc/exports, /etc/dhcpd.conf, /etc/hosts) are now
53populated from the templates."""
54
55# Tokenize input
56input_tokens = tokenizer.convert_ids_to_tokens(
57 tokenizer.encode(input_text, max_length=1024, truncation=True)
58)
59
60# Generate with CTranslate2
61results = translator.translate_batch(
62 [input_tokens],
63 beam_size=6,
64 max_decoding_length=512,
65 no_repeat_ngram_size=4
66)
67
68# Decode output
69changelog = decode_changelog(results[0].hypotheses[0])
70print(changelog)
71# Expected output:
72# - update to v4.3.0rc2 with following major changes:
73# * Provision interface is not tied to 'eth0' any more. The provision interface
74# must be named 'default' now. The file `nodes.yaml' must be changed accordingly.
75# * Creating of '/etc/exports' can now be disabled, so that wwctl configure -a
76# wont overwrite a existing '/etc/exports'.
77# * All configurations files for the host (/etc/exports, /etc/dhcpd.conf,
78# /etc/hosts) are now populated from the templates.| Variant | Size vs Original | Device | Speed |
|---|---|---|---|
| float32 | 100% | CPU/GPU | 2x |
| float16 | 50% | GPU only | 2-3x |
| int8_float16 | 25% | GPU only | 2-4x |
| int8 | 25% | CPU/GPU | 2x |
int8_float16 (best speed/memory balance)int8 (small size, CPU compatible)float32 or float16subfolder parameter to select the variant:1from transformers import T5ForConditionalGeneration, AutoTokenizer
2
3# Repository ID
4repo_id = "mslacken/t5-finetune-changelog"
5
6# Choose one of the three variants:
7# - subfolder="t5-small" (fastest, 231 MB) - NOT recommended
8# - subfolder="t5-base" (balanced, 850 MB)
9# - subfolder="t5-large" (best quality, 2.8 GB) - Recommended
10subfolder = "t5-large"
11
12model = T5ForConditionalGeneration.from_pretrained(repo_id, subfolder=subfolder)
13tokenizer = AutoTokenizer.from_pretrained(repo_id, subfolder=subfolder)
14
15# Helper function to decode while preserving newlines
16def decode_changelog(output_ids):
17 # Decode without removing special tokens first
18 decoded = tokenizer.decode(output_ids, skip_special_tokens=False)
19 # Remove only standard T5 tokens, keep our custom \n token
20 import re
21 decoded = decoded.replace(tokenizer.pad_token or "<pad>", "")
22 decoded = decoded.replace(tokenizer.eos_token or "</s>", "")
23 decoded = re.sub(r"<extra_id_\d+>", "", decoded) # Remove sentinel tokens
24 return decoded.strip()
25
26# Generation parameters (recommended to prevent repetitions):
27# - num_beams=4: Use beam search for better quality
28# - repetition_penalty=1.2: Penalize repeated tokens
29# - no_repeat_ngram_size=3: Prevent 3-word phrase repetition
30# - early_stopping=True: Stop when EOS token is generated
31
32# Example input
33input_text = """create structured changelog for package warewulf4 from 4.2.0 to 4.3.0rc2:
34changelog:
35# Changelog
36All notable changes to this project will be documented in this file.
37The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
38and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
39## [Unreleased]
40### Changed
41- Provision interface is not tied to 'eth0' any more. The provision interface must be named
42'default' now. The file 'nodes.yaml' must be changed accordingly.
43- Creating of '/etc/exports' can now be disabled, so that wwctl configure -a wont overwrite
44a existing '/etc/exports'.
45- All configurations files for the host (/etc/exports, /etc/dhcpd.conf, /etc/hosts) are now
46populated from the templates."""
47
48inputs = tokenizer(input_text, return_tensors="pt", max_length=1024, truncation=True)
49outputs = model.generate(
50 **inputs,
51 max_length=512,
52 num_beams=6,
53 no_repeat_ngram_size=4,
54 early_stopping=True
55)
56changelog = decode_changelog(outputs[0])
57print(changelog)
58# Expected output:
59# - update to v4.3.0rc2 with following major changes:
60# * Provision interface is not tied to 'eth0' any more. The provision interface
61# must be named 'default' now. The file `nodes.yaml' must be changed accordingly.
62# * Creating of '/etc/exports' can now be disabled, so that wwctl configure -a
63# wont overwrite a existing '/etc/exports'.
64# * All configurations files for the host (/etc/exports, /etc/dhcpd.conf,
65# /etc/hosts) are now populated from the templates.1from transformers import T5ForConditionalGeneration, AutoTokenizer
2
3repo_id = "mslacken/t5-finetune-changelog"
4subfolder = "t5-large" # Recommended
5
6# Load model and tokenizer
7model = T5ForConditionalGeneration.from_pretrained(repo_id, subfolder=subfolder)
8tokenizer = AutoTokenizer.from_pretrained(repo_id, subfolder=subfolder)
9
10# Helper function to decode while preserving newlines
11def decode_changelog(output_ids):
12 import re
13 decoded = tokenizer.decode(output_ids, skip_special_tokens=False)
14 decoded = decoded.replace(tokenizer.pad_token or "<pad>", "")
15 decoded = decoded.replace(tokenizer.eos_token or "</s>", "")
16 decoded = re.sub(r"<extra_id_\d+>", "", decoded)
17 return decoded.strip()
18
19# Example input
20input_text = """create structured changelog for package warewulf4 from 4.2.0 to 4.3.0rc2:
21changelog:
22# Changelog
23All notable changes to this project will be documented in this file.
24The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
25and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
26## [Unreleased]
27### Changed
28- Provision interface is not tied to 'eth0' any more. The provision interface must be named
29'default' now. The file 'nodes.yaml' must be changed accordingly.
30- Creating of '/etc/exports' can now be disabled, so that wwctl configure -a wont overwrite
31a existing '/etc/exports'.
32- All configurations files for the host (/etc/exports, /etc/dhcpd.conf, /etc/hosts) are now
33populated from the templates."""
34
35inputs = tokenizer(input_text, return_tensors="pt", max_length=1024, truncation=True)
36outputs = model.generate(
37 **inputs,
38 max_length=512,
39 num_beams=6,
40 no_repeat_ngram_size=4,
41 early_stopping=True
42)
43changelog = decode_changelog(outputs[0])
44print(changelog)
45# Expected output:
46# - update to v4.3.0rc2 with following major changes:
47# * Provision interface is not tied to 'eth0' any more. The provision interface
48# must be named 'default' now. The file `nodes.yaml' must be changed accordingly.
49# * Creating of '/etc/exports' can now be disabled, so that wwctl configure -a
50# wont overwrite a existing '/etc/exports'.
51# * All configurations files for the host (/etc/exports, /etc/dhcpd.conf,
52# /etc/hosts) are now populated from the templates.google-t5/t5-small (60M parameters)google-t5/t5-base (220M parameters)google-t5/t5-large (770M parameters)\n as additional special token for better diff handlinggenerate changelog: [code diff or change description][Human-readable changelog entry]t5-finetune-changelog/
├── t5-small/ # 231 MB (NOT recommended - hallucinates)
│ ├── config.json
│ ├── generation_config.json
│ ├── model.safetensors
│ ├── tokenizer.json
│ └── tokenizer_config.json
├── t5-base/ # 850 MB - Balanced
│ └── [same files]
├── t5-large/ # 2.8 GB - Best quality (Recommended)
│ └── [same files]
└── ct2_models/ # CTranslate2 optimized models (2-4x faster inference)
├── t5-base-ct2-float32/ # Full precision (~850 MB)
├── t5-base-ct2-float16/ # GPU only (~425 MB)
├── t5-base-ct2-int8_float16/ # GPU only (~220 MB)
├── t5-base-ct2-int8/ # CPU/GPU compatible (~220 MB)
├── t5-large-ct2-float32/ # Full precision (~2.8 GB)
├── t5-large-ct2-float16/ # GPU only (~1.4 GB)
├── t5-large-ct2-int8_float16/ # GPU only (~770 MB)
└── t5-large-ct2-int8/ # CPU/GPU compatible (~770 MB)1@misc{t5-changelog-collection-2026,
2 author = {Christian Goll},
3 title = {T5 Changelog Generator Collection},
4 year = {2026},
5 publisher = {Hugging Face},
6 howpublished = {\url{https://huggingface.co/mslacken/t5-finetune-changelog}}
7}