update
This commit is contained in:
parent
cdd3b3fc30
commit
50d0581424
89
configs/training_args_unsloth_.yaml
Normal file
89
configs/training_args_unsloth_.yaml
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
top.booster: unsloth
|
||||||
|
top.checkpoint_path: []
|
||||||
|
top.finetuning_type: lora
|
||||||
|
top.model_name: Custom
|
||||||
|
top.quantization_bit: '4'
|
||||||
|
top.quantization_method: bnb
|
||||||
|
top.rope_scaling: none
|
||||||
|
top.template: alpaca
|
||||||
|
train.additional_target: ''
|
||||||
|
train.apollo_rank: 16
|
||||||
|
train.apollo_scale: 32
|
||||||
|
train.apollo_target: all
|
||||||
|
train.apollo_update_interval: 200
|
||||||
|
train.badam_mode: layer
|
||||||
|
train.badam_switch_interval: 50
|
||||||
|
train.badam_switch_mode: ascending
|
||||||
|
train.badam_update_ratio: 0.05
|
||||||
|
train.batch_size: 1
|
||||||
|
train.compute_type: fp16
|
||||||
|
train.create_new_adapter: false
|
||||||
|
train.cutoff_len: 1024
|
||||||
|
train.dataset:
|
||||||
|
- alpaca_slovak_cleaned
|
||||||
|
train.dataset_dir: data
|
||||||
|
train.ds_offload: false
|
||||||
|
train.ds_stage: none
|
||||||
|
train.enable_thinking: false
|
||||||
|
train.extra_args: '{"optim": "adamw_8bit", "eval_steps": 1000, "eval_strategy": "steps",
|
||||||
|
"save_total_limit": 2}'
|
||||||
|
train.freeze_extra_modules: ''
|
||||||
|
train.freeze_language_model: false
|
||||||
|
train.freeze_multi_modal_projector: true
|
||||||
|
train.freeze_trainable_layers: 2
|
||||||
|
train.freeze_trainable_modules: all
|
||||||
|
train.freeze_vision_tower: true
|
||||||
|
train.galore_rank: 16
|
||||||
|
train.galore_scale: 2
|
||||||
|
train.galore_target: all
|
||||||
|
train.galore_update_interval: 200
|
||||||
|
train.gradient_accumulation_steps: 8
|
||||||
|
train.hub_private_repo: false
|
||||||
|
train.image_max_pixels: 768*768
|
||||||
|
train.image_min_pixels: 32*32
|
||||||
|
train.learning_rate: 2e-4
|
||||||
|
train.logging_steps: 5
|
||||||
|
train.lora_alpha: 32
|
||||||
|
train.lora_dropout: 0.05
|
||||||
|
train.lora_rank: 16
|
||||||
|
train.lora_target: q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj
|
||||||
|
train.loraplus_lr_ratio: 0
|
||||||
|
train.lr_scheduler_type: cosine
|
||||||
|
train.mask_history: false
|
||||||
|
train.max_grad_norm: '1.0'
|
||||||
|
train.max_samples: '50000'
|
||||||
|
train.neat_packing: false
|
||||||
|
train.neftune_alpha: 0
|
||||||
|
train.num_train_epochs: '1.0'
|
||||||
|
train.packing: false
|
||||||
|
train.ppo_score_norm: false
|
||||||
|
train.ppo_whiten_rewards: false
|
||||||
|
train.pref_beta: 0.1
|
||||||
|
train.pref_ftx: 0
|
||||||
|
train.pref_loss: sigmoid
|
||||||
|
train.project: huggingface
|
||||||
|
train.report_to: none
|
||||||
|
train.resize_vocab: false
|
||||||
|
train.reward_model: []
|
||||||
|
train.save_steps: 1000
|
||||||
|
train.swanlab_api_key: ''
|
||||||
|
train.swanlab_link: null
|
||||||
|
train.swanlab_mode: cloud
|
||||||
|
train.swanlab_project: llamafactory
|
||||||
|
train.swanlab_run_name: ''
|
||||||
|
train.swanlab_workspace: ''
|
||||||
|
train.trackio_space_id: trackio
|
||||||
|
train.train_on_prompt: false
|
||||||
|
train.training_stage: Supervised Fine-Tuning
|
||||||
|
train.use_apollo: false
|
||||||
|
train.use_badam: false
|
||||||
|
train.use_dora: false
|
||||||
|
train.use_galore: false
|
||||||
|
train.use_llama_pro: false
|
||||||
|
train.use_pissa: false
|
||||||
|
train.use_rslora: false
|
||||||
|
train.use_swanlab: false
|
||||||
|
train.val_size: 0.025
|
||||||
|
train.video_max_pixels: 256*256
|
||||||
|
train.video_min_pixels: 16*16
|
||||||
|
train.warmup_steps: 150
|
||||||
26
evaluation/lmeval_custom_tasks/sklegal.yaml
Normal file
26
evaluation/lmeval_custom_tasks/sklegal.yaml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
task: sklegal
|
||||||
|
repeats: 1
|
||||||
|
metadata:
|
||||||
|
version: 1
|
||||||
|
test_split: test
|
||||||
|
description: ''
|
||||||
|
doc_to_text: '{{prompt}} '
|
||||||
|
metric_list:
|
||||||
|
- metric: acc
|
||||||
|
aggregation: mean
|
||||||
|
higher_is_better: true
|
||||||
|
- metric: acc_norm
|
||||||
|
aggregation: mean
|
||||||
|
higher_is_better: true
|
||||||
|
num_fewshot: 0
|
||||||
|
output_type: multiple_choice
|
||||||
|
unsafe_code: false
|
||||||
|
dataset_path: TUKE-KEMT/slovak-legal-exam
|
||||||
|
doc_to_choice: '{{answers}}'
|
||||||
|
doc_to_target: label
|
||||||
|
target_delimiter: ' '
|
||||||
|
fewshot_delimiter: '
|
||||||
|
|
||||||
|
|
||||||
|
'
|
||||||
|
should_decontaminate: false
|
||||||
2
evaluation/lmeval_custom_tasks/skquad.yaml
Normal file
2
evaluation/lmeval_custom_tasks/skquad.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
task: skquad
|
||||||
|
class: !function task.SQuAD2
|
||||||
245
evaluation/lmeval_custom_tasks/task.py
Normal file
245
evaluation/lmeval_custom_tasks/task.py
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
"""
|
||||||
|
Know What You Don’t Know: Unanswerable Questions for SQuAD
|
||||||
|
https://arxiv.org/pdf/1806.03822.pdf
|
||||||
|
|
||||||
|
Stanford Question Answering Dataset (SQuAD) is a reading comprehension dataset,
|
||||||
|
consisting of questions posed by crowdworkers on a set of Wikipedia articles,
|
||||||
|
where the answer to every question is a segment of text, or span, from the
|
||||||
|
corresponding reading passage, or the question might be unanswerable.
|
||||||
|
SQuAD2.0 combines the 100,000 questions in SQuAD1.1 with over 50,000 unanswerable
|
||||||
|
questions written adversarially by crowdworkers to look similar to answerable ones.
|
||||||
|
To do well on SQuAD2.0, systems must not only answer questions when possible, but
|
||||||
|
also determine when no answer is supported by the paragraph and abstain from answering.
|
||||||
|
|
||||||
|
Homepage: https://rajpurkar.github.io/SQuAD-explorer/
|
||||||
|
"""
|
||||||
|
|
||||||
|
from functools import partial
|
||||||
|
from math import exp
|
||||||
|
|
||||||
|
import datasets
|
||||||
|
from packaging import version
|
||||||
|
|
||||||
|
from lm_eval.api.instance import Instance
|
||||||
|
from lm_eval.api.task import ConfigurableTask
|
||||||
|
|
||||||
|
|
||||||
|
_CITATION = """
|
||||||
|
@misc{rajpurkar2018know,
|
||||||
|
title={Know What You Don't Know: Unanswerable Questions for SQuAD},
|
||||||
|
author={Pranav Rajpurkar and Robin Jia and Percy Liang},
|
||||||
|
year={2018},
|
||||||
|
eprint={1806.03822},
|
||||||
|
archivePrefix={arXiv},
|
||||||
|
primaryClass={cs.CL}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def _squad_metric(predictions, references):
|
||||||
|
import evaluate
|
||||||
|
|
||||||
|
squad_metric = evaluate.load("squad_v2")
|
||||||
|
return squad_metric.compute(predictions=predictions, references=references)
|
||||||
|
|
||||||
|
|
||||||
|
def _squad_agg(key, items):
|
||||||
|
predictions, references = zip(*items)
|
||||||
|
|
||||||
|
return _squad_metric(predictions=predictions, references=references).get(key, 0)
|
||||||
|
|
||||||
|
|
||||||
|
class SQuAD2(ConfigurableTask):
|
||||||
|
VERSION = 3
|
||||||
|
DATASET_PATH = "TUKE-DeutscheTelekom/skquad"
|
||||||
|
DATASET_NAME = None
|
||||||
|
|
||||||
|
def __init__(self, config=None):
|
||||||
|
super().__init__(config={"metadata": {"version": self.VERSION}})
|
||||||
|
|
||||||
|
# HF changed squad on us so we have to make sure we aren't running the old one
|
||||||
|
assert version.parse(datasets.__version__) >= version.parse("1.11.0"), (
|
||||||
|
"datasets v1.11.0 or later required for SQuAD"
|
||||||
|
)
|
||||||
|
|
||||||
|
def has_training_docs(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def has_validation_docs(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def has_test_docs(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def training_docs(self):
|
||||||
|
return self.dataset["train"]
|
||||||
|
|
||||||
|
def validation_docs(self):
|
||||||
|
return self.dataset["validation"]
|
||||||
|
|
||||||
|
def doc_to_text(self, doc):
|
||||||
|
return (
|
||||||
|
"Title: "
|
||||||
|
+ doc["title"]
|
||||||
|
+ "\n\n"
|
||||||
|
+ "Background: "
|
||||||
|
+ doc["context"]
|
||||||
|
+ "\n\n"
|
||||||
|
+ "Question: "
|
||||||
|
+ doc["question"]
|
||||||
|
+ "\n\n"
|
||||||
|
+ "Answer:"
|
||||||
|
)
|
||||||
|
|
||||||
|
def should_decontaminate(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def doc_to_decontamination_query(self, doc):
|
||||||
|
return doc["context"]
|
||||||
|
|
||||||
|
def doc_to_target(self, doc):
|
||||||
|
answer_list = doc["answers"]["text"]
|
||||||
|
if len(answer_list) > 0:
|
||||||
|
answer = answer_list[0]
|
||||||
|
else:
|
||||||
|
answer = "unanswerable"
|
||||||
|
return " " + answer
|
||||||
|
|
||||||
|
def construct_requests(
|
||||||
|
self, doc, ctx, chat_template=None, apply_chat_template=False, **kwargs
|
||||||
|
):
|
||||||
|
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||||
|
Requests which will be sent to the LM.
|
||||||
|
|
||||||
|
:param doc:
|
||||||
|
The document as returned from training_docs, validation_docs, or test_docs.
|
||||||
|
:param ctx: str
|
||||||
|
The context string, generated by fewshot_context. This includes the natural
|
||||||
|
language description, as well as the few shot examples, and the question
|
||||||
|
part of the document for `doc`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return [
|
||||||
|
Instance(
|
||||||
|
request_type="generate_until",
|
||||||
|
doc=doc,
|
||||||
|
arguments=(ctx, {"until": ["\n"]}),
|
||||||
|
idx=0,
|
||||||
|
**kwargs,
|
||||||
|
),
|
||||||
|
Instance(
|
||||||
|
request_type="loglikelihood",
|
||||||
|
doc=doc,
|
||||||
|
arguments=(ctx, " " + "unanswerable"),
|
||||||
|
idx=0,
|
||||||
|
**kwargs,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
def process_results(self, doc, results):
|
||||||
|
"""Take a single document and the LM results and evaluates, returning a
|
||||||
|
dict where keys are the names of submetrics and values are the values of
|
||||||
|
the metric for that one document
|
||||||
|
|
||||||
|
:param doc:
|
||||||
|
The document as returned from training_docs, validation_docs, or test_docs.
|
||||||
|
:param results:
|
||||||
|
The results of the requests created in construct_requests.
|
||||||
|
"""
|
||||||
|
|
||||||
|
continuation, (logprob_unanswerable, _) = results
|
||||||
|
|
||||||
|
no_answer_probability = exp(logprob_unanswerable)
|
||||||
|
|
||||||
|
predictions = {
|
||||||
|
"id": doc["id"],
|
||||||
|
"prediction_text": continuation,
|
||||||
|
"no_answer_probability": no_answer_probability,
|
||||||
|
}
|
||||||
|
|
||||||
|
references = {
|
||||||
|
"id": doc["id"],
|
||||||
|
"answers": doc["answers"],
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"exact": (
|
||||||
|
predictions,
|
||||||
|
references,
|
||||||
|
), # Exact match (the normalized answer exactly match the gold answer)
|
||||||
|
"f1": (
|
||||||
|
predictions,
|
||||||
|
references,
|
||||||
|
), # The F-score of predicted tokens versus the gold answer
|
||||||
|
"HasAns_exact": (
|
||||||
|
predictions,
|
||||||
|
references,
|
||||||
|
), # Exact match (the normalized answer exactly match the gold answer)
|
||||||
|
"HasAns_f1": (
|
||||||
|
predictions,
|
||||||
|
references,
|
||||||
|
), # The F-score of predicted tokens versus the gold answer
|
||||||
|
"NoAns_exact": (
|
||||||
|
predictions,
|
||||||
|
references,
|
||||||
|
), # Exact match (the normalized answer exactly match the gold answer)
|
||||||
|
"NoAns_f1": (
|
||||||
|
predictions,
|
||||||
|
references,
|
||||||
|
), # The F-score of predicted tokens versus the gold answer
|
||||||
|
"best_exact": (
|
||||||
|
predictions,
|
||||||
|
references,
|
||||||
|
), # Best exact match (with varying threshold)
|
||||||
|
"best_f1": (predictions, references), # Best F1 (with varying threshold)
|
||||||
|
}
|
||||||
|
|
||||||
|
def aggregation(self):
|
||||||
|
"""
|
||||||
|
:returns: {str: [float] -> float}
|
||||||
|
A dictionary where keys are the names of submetrics and values are
|
||||||
|
functions that aggregate a list of metrics
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"exact": partial(
|
||||||
|
_squad_agg, "exact"
|
||||||
|
), # Exact match (the normalized answer exactly match the gold answer)
|
||||||
|
"f1": partial(
|
||||||
|
_squad_agg, "f1"
|
||||||
|
), # The F-score of predicted tokens versus the gold answer
|
||||||
|
"HasAns_exact": partial(
|
||||||
|
_squad_agg, "HasAns_exact"
|
||||||
|
), # Exact match (the normalized answer exactly match the gold answer)
|
||||||
|
"HasAns_f1": partial(
|
||||||
|
_squad_agg, "HasAns_f1"
|
||||||
|
), # The F-score of predicted tokens versus the gold answer
|
||||||
|
"NoAns_exact": partial(
|
||||||
|
_squad_agg, "NoAns_exact"
|
||||||
|
), # Exact match (the normalized answer exactly match the gold answer)
|
||||||
|
"NoAns_f1": partial(
|
||||||
|
_squad_agg, "NoAns_f1"
|
||||||
|
), # The F-score of predicted tokens versus the gold answer
|
||||||
|
"best_exact": partial(
|
||||||
|
_squad_agg, "best_exact"
|
||||||
|
), # Best exact match (with varying threshold)
|
||||||
|
"best_f1": partial(
|
||||||
|
_squad_agg, "best_f1"
|
||||||
|
), # Best F1 (with varying threshold)
|
||||||
|
}
|
||||||
|
|
||||||
|
def higher_is_better(self):
|
||||||
|
"""
|
||||||
|
:returns: {str: bool}
|
||||||
|
A dictionary where keys are the names of submetrics and values are
|
||||||
|
whether a higher value of the submetric is better
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"exact": True, # Exact match (the normalized answer exactly match the gold answer)
|
||||||
|
"f1": True, # The F-score of predicted tokens versus the gold answer
|
||||||
|
"HasAns_exact": True, # Exact match (the normalized answer exactly match the gold answer)
|
||||||
|
"HasAns_f1": True, # The F-score of predicted tokens versus the gold answer
|
||||||
|
"NoAns_exact": True, # Exact match (the normalized answer exactly match the gold answer)
|
||||||
|
"NoAns_f1": True, # The F-score of predicted tokens versus the gold answer
|
||||||
|
"best_exact": True, # Best exact match (with varying threshold)
|
||||||
|
"best_f1": True, # Best F1 (with varying threshold)
|
||||||
|
}
|
||||||
@ -1,43 +0,0 @@
|
|||||||
cutoff_len: 1024
|
|
||||||
dataset: alpaca_slovak_cleaned
|
|
||||||
dataset_dir: data
|
|
||||||
ddp_timeout: 180000000
|
|
||||||
do_train: true
|
|
||||||
double_quantization: true
|
|
||||||
enable_thinking: false
|
|
||||||
eval_steps: 1000
|
|
||||||
eval_strategy: steps
|
|
||||||
finetuning_type: lora
|
|
||||||
flash_attn: auto
|
|
||||||
fp16: true
|
|
||||||
gradient_accumulation_steps: 8
|
|
||||||
include_num_input_tokens_seen: true
|
|
||||||
learning_rate: 0.0002
|
|
||||||
logging_steps: 5
|
|
||||||
lora_alpha: 32
|
|
||||||
lora_dropout: 0.05
|
|
||||||
lora_rank: 16
|
|
||||||
lora_target: q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj
|
|
||||||
lr_scheduler_type: cosine
|
|
||||||
max_grad_norm: 1.0
|
|
||||||
max_samples: 50000
|
|
||||||
model_name_or_path: slovak-nlp/mistral-sk-7b
|
|
||||||
num_train_epochs: 1.0
|
|
||||||
optim: adamw_8bit
|
|
||||||
output_dir: /home/schwarc/diplomovka/mistral_sk_alpaca/llamafactory-full-lora
|
|
||||||
packing: false
|
|
||||||
per_device_eval_batch_size: 1
|
|
||||||
per_device_train_batch_size: 1
|
|
||||||
plot_loss: true
|
|
||||||
preprocessing_num_workers: 16
|
|
||||||
quantization_bit: 4
|
|
||||||
quantization_method: bnb
|
|
||||||
report_to: none
|
|
||||||
save_steps: 1000
|
|
||||||
save_total_limit: 2
|
|
||||||
stage: sft
|
|
||||||
template: alpaca
|
|
||||||
trust_remote_code: true
|
|
||||||
use_unsloth: true
|
|
||||||
val_size: 0.025
|
|
||||||
warmup_steps: 150
|
|
||||||
BIN
plots/lmeval_main_metrics_chart.pdf
Normal file
BIN
plots/lmeval_main_metrics_chart.pdf
Normal file
Binary file not shown.
BIN
plots/lmeval_main_metrics_chart.png
Normal file
BIN
plots/lmeval_main_metrics_chart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 197 KiB |
18
results/lmeval_results_full_table.csv
Normal file
18
results/lmeval_results_full_table.csv
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
task,samples,metric,value,model,adapter
|
||||||
|
arc_sk,1169,acc,0.3259,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
arc_sk,1169,acc_norm,0.3473,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
hellaswag_sk,9485,acc,0.4134,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
hellaswag_sk,9485,acc_norm,0.5106,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
m_mmlu_sk,13062,acc,0.2928,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
truthfulqa_sk_mc1,778,acc,0.2391,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
truthfulqa_sk_mc2,778,acc,0.3942,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
sklegal,1334,acc,0.2841,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
sklegal,1334,acc_norm,0.4693,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
skquad,9583,exact,1.9722,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
skquad,9583,f1,27.7994,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
skquad,9583,HasAns_exact,2.4106,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
skquad,9583,HasAns_f1,34.1456,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
skquad,9583,NoAns_exact,0.0561,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
skquad,9583,NoAns_f1,0.0561,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
skquad,9583,best_exact,18.6163,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
skquad,9583,best_f1,28.3012,slovak-nlp/mistral-sk-7b,Jakub1320/mistral-sk-7b-slovak-alpaca-qlora
|
||||||
|
@ -18,7 +18,6 @@ import sacrebleu
|
|||||||
MODEL_NAME = "slovak-nlp/mistral-sk-7b"
|
MODEL_NAME = "slovak-nlp/mistral-sk-7b"
|
||||||
DATASET_NAME = "saillab/alpaca-slovak-cleaned"
|
DATASET_NAME = "saillab/alpaca-slovak-cleaned"
|
||||||
|
|
||||||
# Tvoj Unsloth + TRL + QLoRA adaptér
|
|
||||||
ADAPTER_DIR = "/home/schwarc/diplomovka/mistral_sk_alpaca/mistral-sk-7b-alpaca-slovak-unsloth-lora-full"
|
ADAPTER_DIR = "/home/schwarc/diplomovka/mistral_sk_alpaca/mistral-sk-7b-alpaca-slovak-unsloth-lora-full"
|
||||||
|
|
||||||
PROJECT_DIR = Path.home() / "diplomovka" / "evaluation_results"
|
PROJECT_DIR = Path.home() / "diplomovka" / "evaluation_results"
|
||||||
@ -30,7 +29,7 @@ NUM_EVAL_SAMPLES = 1000
|
|||||||
MAX_LENGTH = 1024
|
MAX_LENGTH = 1024
|
||||||
MAX_NEW_TOKENS = 300
|
MAX_NEW_TOKENS = 300
|
||||||
|
|
||||||
# Pri hodnotení je lepšie deterministické generovanie
|
|
||||||
DO_SAMPLE = False
|
DO_SAMPLE = False
|
||||||
|
|
||||||
|
|
||||||
100
scripts/plot_lmeval_results.py
Normal file
100
scripts/plot_lmeval_results.py
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import pandas as pd
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
OUT_DIR = Path("/home/schwarc/diplomovka/lmeval_plots")
|
||||||
|
OUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
MODEL = "slovak-nlp/mistral-sk-7b"
|
||||||
|
ADAPTER = "Jakub1320/mistral-sk-7b-slovak-alpaca-qlora"
|
||||||
|
|
||||||
|
rows = [
|
||||||
|
{"task": "arc_sk", "samples": 1169, "metric": "acc", "value": 0.3259},
|
||||||
|
{"task": "arc_sk", "samples": 1169, "metric": "acc_norm", "value": 0.3473},
|
||||||
|
|
||||||
|
{"task": "hellaswag_sk", "samples": 9485, "metric": "acc", "value": 0.4134},
|
||||||
|
{"task": "hellaswag_sk", "samples": 9485, "metric": "acc_norm", "value": 0.5106},
|
||||||
|
|
||||||
|
{"task": "m_mmlu_sk", "samples": 13062, "metric": "acc", "value": 0.2928},
|
||||||
|
|
||||||
|
{"task": "truthfulqa_sk_mc1", "samples": 778, "metric": "acc", "value": 0.2391},
|
||||||
|
{"task": "truthfulqa_sk_mc2", "samples": 778, "metric": "acc", "value": 0.3942},
|
||||||
|
|
||||||
|
{"task": "sklegal", "samples": 1334, "metric": "acc", "value": 0.2841},
|
||||||
|
{"task": "sklegal", "samples": 1334, "metric": "acc_norm", "value": 0.4693},
|
||||||
|
|
||||||
|
{"task": "skquad", "samples": 9583, "metric": "exact", "value": 1.9722},
|
||||||
|
{"task": "skquad", "samples": 9583, "metric": "f1", "value": 27.7994},
|
||||||
|
{"task": "skquad", "samples": 9583, "metric": "HasAns_exact", "value": 2.4106},
|
||||||
|
{"task": "skquad", "samples": 9583, "metric": "HasAns_f1", "value": 34.1456},
|
||||||
|
{"task": "skquad", "samples": 9583, "metric": "NoAns_exact", "value": 0.0561},
|
||||||
|
{"task": "skquad", "samples": 9583, "metric": "NoAns_f1", "value": 0.0561},
|
||||||
|
{"task": "skquad", "samples": 9583, "metric": "best_exact", "value": 18.6163},
|
||||||
|
{"task": "skquad", "samples": 9583, "metric": "best_f1", "value": 28.3012},
|
||||||
|
]
|
||||||
|
|
||||||
|
df = pd.DataFrame(rows)
|
||||||
|
df["model"] = MODEL
|
||||||
|
df["adapter"] = ADAPTER
|
||||||
|
|
||||||
|
csv_path = OUT_DIR / "lmeval_results_full_table.csv"
|
||||||
|
df.to_csv(csv_path, index=False)
|
||||||
|
|
||||||
|
# Skrátený výber hlavných metrík pre graf
|
||||||
|
|
||||||
|
main_rows = [
|
||||||
|
{"benchmark": "ARC-SK", "metric": "acc_norm", "score_percent": 34.73},
|
||||||
|
{"benchmark": "HellaSwag-SK", "metric": "acc_norm", "score_percent": 51.06},
|
||||||
|
{"benchmark": "M-MMLU-SK", "metric": "acc", "score_percent": 29.28},
|
||||||
|
{"benchmark": "TruthfulQA-SK MC1", "metric": "acc", "score_percent": 23.91},
|
||||||
|
{"benchmark": "TruthfulQA-SK MC2", "metric": "acc", "score_percent": 39.42},
|
||||||
|
{"benchmark": "SKLegal", "metric": "acc_norm", "score_percent": 46.93},
|
||||||
|
{"benchmark": "SKQuAD", "metric": "f1", "score_percent": 27.80},
|
||||||
|
]
|
||||||
|
|
||||||
|
main_df = pd.DataFrame(main_rows)
|
||||||
|
main_csv_path = OUT_DIR / "lmeval_main_metrics_table.csv"
|
||||||
|
main_df.to_csv(main_csv_path, index=False)
|
||||||
|
|
||||||
|
# Graf hlavných metrík
|
||||||
|
labels = main_df["benchmark"] + " (" + main_df["metric"] + ")"
|
||||||
|
scores = main_df["score_percent"]
|
||||||
|
|
||||||
|
plt.figure(figsize=(11, 6))
|
||||||
|
bars = plt.barh(labels, scores)
|
||||||
|
|
||||||
|
plt.xlabel("Skóre (%)")
|
||||||
|
plt.ylabel("Benchmark")
|
||||||
|
plt.title("Výsledky lm-evaluation-harness pre PEFT LoRA model")
|
||||||
|
plt.xlim(0, 60)
|
||||||
|
plt.gca().invert_yaxis()
|
||||||
|
|
||||||
|
for bar, score in zip(bars, scores):
|
||||||
|
plt.text(
|
||||||
|
bar.get_width() + 0.8,
|
||||||
|
bar.get_y() + bar.get_height() / 2,
|
||||||
|
f"{score:.2f} %",
|
||||||
|
va="center"
|
||||||
|
)
|
||||||
|
|
||||||
|
plt.figtext(
|
||||||
|
0.01,
|
||||||
|
0.01,
|
||||||
|
f"Model: {MODEL} | Adaptér: {ADAPTER}",
|
||||||
|
fontsize=8
|
||||||
|
)
|
||||||
|
|
||||||
|
plt.tight_layout(rect=[0, 0.04, 1, 1])
|
||||||
|
|
||||||
|
png_path = OUT_DIR / "lmeval_main_metrics_chart.png"
|
||||||
|
pdf_path = OUT_DIR / "lmeval_main_metrics_chart.pdf"
|
||||||
|
|
||||||
|
plt.savefig(png_path, dpi=300)
|
||||||
|
plt.savefig(pdf_path)
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
print("Hotovo.")
|
||||||
|
print(f"CSV kompletna tabulka: {csv_path}")
|
||||||
|
print(f"CSV hlavne metriky: {main_csv_path}")
|
||||||
|
print(f"Graf PNG: {png_path}")
|
||||||
|
print(f"Graf PDF: {pdf_path}")
|
||||||
173
strojovy_preklad/translate_dataset_to_slovak.py
Normal file
173
strojovy_preklad/translate_dataset_to_slovak.py
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import torch
|
||||||
|
from datasets import load_dataset
|
||||||
|
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Nastavenia
|
||||||
|
# -----------------------------
|
||||||
|
|
||||||
|
DATASET_NAME = "tatsu-lab/alpaca"
|
||||||
|
SPLIT = "train"
|
||||||
|
|
||||||
|
OUTPUT_DIR = Path("/home/schwarc/diplomovka/translated_datasets")
|
||||||
|
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
OUTPUT_FILE = OUTPUT_DIR / "alpaca_translated_en_sk_1000.jsonl"
|
||||||
|
|
||||||
|
MAX_SAMPLES = 1000
|
||||||
|
|
||||||
|
TRANSLATION_MODEL = "facebook/nllb-200-distilled-600M"
|
||||||
|
|
||||||
|
SOURCE_LANG = "eng_Latn"
|
||||||
|
TARGET_LANG = "slk_Latn"
|
||||||
|
|
||||||
|
BATCH_SIZE = 8
|
||||||
|
MAX_INPUT_LENGTH = 1024
|
||||||
|
MAX_NEW_TOKENS = 512
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Pomocné funkcie
|
||||||
|
|
||||||
|
def is_empty(value):
|
||||||
|
if value is None:
|
||||||
|
return True
|
||||||
|
value = str(value).strip()
|
||||||
|
return value == "" or value.lower() == "nan"
|
||||||
|
|
||||||
|
|
||||||
|
def load_already_done(path):
|
||||||
|
"""
|
||||||
|
Ak skript spadne alebo ho zastavíš, vie pokračovať.
|
||||||
|
Načíta už preložené riadky.
|
||||||
|
"""
|
||||||
|
if not path.exists():
|
||||||
|
return []
|
||||||
|
|
||||||
|
rows = []
|
||||||
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
if line.strip():
|
||||||
|
rows.append(json.loads(line))
|
||||||
|
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def translate_batch(texts, tokenizer, model, device):
|
||||||
|
"""
|
||||||
|
Preloží batch textov z angličtiny do slovenčiny.
|
||||||
|
Prázdne texty nechá prázdne.
|
||||||
|
"""
|
||||||
|
results = [""] * len(texts)
|
||||||
|
|
||||||
|
non_empty_indices = []
|
||||||
|
non_empty_texts = []
|
||||||
|
|
||||||
|
for i, text in enumerate(texts):
|
||||||
|
if is_empty(text):
|
||||||
|
results[i] = ""
|
||||||
|
else:
|
||||||
|
non_empty_indices.append(i)
|
||||||
|
non_empty_texts.append(str(text).strip())
|
||||||
|
|
||||||
|
if not non_empty_texts:
|
||||||
|
return results
|
||||||
|
|
||||||
|
tokenizer.src_lang = SOURCE_LANG
|
||||||
|
|
||||||
|
inputs = tokenizer(
|
||||||
|
non_empty_texts,
|
||||||
|
return_tensors="pt",
|
||||||
|
padding=True,
|
||||||
|
truncation=True,
|
||||||
|
max_length=MAX_INPUT_LENGTH,
|
||||||
|
).to(device)
|
||||||
|
|
||||||
|
forced_bos_token_id = tokenizer.convert_tokens_to_ids(TARGET_LANG)
|
||||||
|
|
||||||
|
with torch.no_grad():
|
||||||
|
generated_tokens = model.generate(
|
||||||
|
**inputs,
|
||||||
|
forced_bos_token_id=forced_bos_token_id,
|
||||||
|
max_new_tokens=MAX_NEW_TOKENS,
|
||||||
|
num_beams=4,
|
||||||
|
)
|
||||||
|
|
||||||
|
translated = tokenizer.batch_decode(
|
||||||
|
generated_tokens,
|
||||||
|
skip_special_tokens=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
for idx, translation in zip(non_empty_indices, translated):
|
||||||
|
results[idx] = translation.strip()
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
# Main
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("Loading dataset...")
|
||||||
|
dataset = load_dataset(DATASET_NAME, split=SPLIT)
|
||||||
|
|
||||||
|
if MAX_SAMPLES is not None:
|
||||||
|
dataset = dataset.select(range(min(MAX_SAMPLES, len(dataset))))
|
||||||
|
|
||||||
|
print(f"Dataset size: {len(dataset)}")
|
||||||
|
|
||||||
|
print("Loading translation model...")
|
||||||
|
device = "cuda" if torch.cuda.is_available() else "cpu"
|
||||||
|
print(f"Device: {device}")
|
||||||
|
|
||||||
|
tokenizer = AutoTokenizer.from_pretrained(TRANSLATION_MODEL)
|
||||||
|
model = AutoModelForSeq2SeqLM.from_pretrained(
|
||||||
|
TRANSLATION_MODEL,
|
||||||
|
torch_dtype=torch.float16 if device == "cuda" else torch.float32,
|
||||||
|
).to(device)
|
||||||
|
|
||||||
|
model.eval()
|
||||||
|
|
||||||
|
already_done = load_already_done(OUTPUT_FILE)
|
||||||
|
start_idx = len(already_done)
|
||||||
|
|
||||||
|
print(f"Already translated: {start_idx}")
|
||||||
|
print(f"Output file: {OUTPUT_FILE}")
|
||||||
|
|
||||||
|
with open(OUTPUT_FILE, "a", encoding="utf-8") as out_f:
|
||||||
|
for start in range(start_idx, len(dataset), BATCH_SIZE):
|
||||||
|
end = min(start + BATCH_SIZE, len(dataset))
|
||||||
|
batch = dataset[start:end]
|
||||||
|
|
||||||
|
instructions_en = batch["instruction"]
|
||||||
|
inputs_en = batch["input"]
|
||||||
|
outputs_en = batch["output"]
|
||||||
|
|
||||||
|
instructions_sk = translate_batch(instructions_en, tokenizer, model, device)
|
||||||
|
inputs_sk = translate_batch(inputs_en, tokenizer, model, device)
|
||||||
|
outputs_sk = translate_batch(outputs_en, tokenizer, model, device)
|
||||||
|
|
||||||
|
for i in range(end - start):
|
||||||
|
row = {
|
||||||
|
"id": start + i,
|
||||||
|
"instruction_en": instructions_en[i],
|
||||||
|
"input_en": inputs_en[i],
|
||||||
|
"output_en": outputs_en[i],
|
||||||
|
"instruction_sk": instructions_sk[i],
|
||||||
|
"input_sk": inputs_sk[i],
|
||||||
|
"output_sk": outputs_sk[i],
|
||||||
|
}
|
||||||
|
|
||||||
|
out_f.write(json.dumps(row, ensure_ascii=False) + "\n")
|
||||||
|
out_f.flush()
|
||||||
|
|
||||||
|
print(f"Translated {end}/{len(dataset)}")
|
||||||
|
|
||||||
|
print("Done.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Reference in New Issue
Block a user