--- library_name: transformers license: apache-2.0 datasets: - Vikhrmodels/GrandMaster-PRO-MAX language: - ru base_model: - RefalMachine/RuadaptQwen2.5-32B-Pro-Beta --- # Watari 32B (V0) - [EN] Qwen2.5-based model, adapted for russian text generation tasks. The model has extended tokenizer and proper adapted chat template. The model was trained using LoRA adapters. - [RU] Finetune версия Qwen2.5, адаптированная для генерации русского текста. Модель имеет расширенный токенайзер и правильный адаптированный чат темплейт (произведена работа над ошибками). Модель была обучена с использованием низкоранговых адаптеров LoRA. ### Previous models (considering parameters): - Watari-7b-v1 ## Model Details / Детализация модели - [EN] LoRA supervised finetuning version was performed on 2xA100 NVIDIA GPUs for ~5 days for 0.6 epochs on dataset: GrandMaster [Vikhrmodels/GrandMaster-PRO-MAX] The model has extended tokenizer based on arxiv paper and works of RefalMachine (RuAdapt / Moscow State University). **Huge thanks to Mikhail Tikhomirov for hard scientific work and tokenizer extension methods developed.** The model generation in russian is 60% more cheaper and faster due to the extended tokenizer (see the research at the end). - [RU] SFT LoRA обучение было выполнено на двух NVIDIA A100, обучение длилось около 5 дней. Прогон ~0.6 эпохи датасета GrandMaster [Vikhrmodels/GrandMaster-PRO-MAX] Модель имеет расширенный токенайзер, метод основан на arxiv статье и работах RefalMachine (RuAdapt / Московский Государственный Университет). **Выражаю большое уважение Михаилу Тихомирову за его научные работы и методы расширения токенайзера.** Генерация модели, благодаря методу на 60% более быстрая и менее дорогая (см. исследование токенайзера в конце статьи). ### Model Description / Описание модели - **Developed by:** [Reisen Raumberg (Attention Signs team)] - **Language(s) (NLP):** [RU/EN] - **Finetuned from model:** [Qwen2.5] Utilized DeepSpeed (Stage 3), HF.Accelerator for distributed training and fused AdamW. **GPU hours**: ~240h of NVIDIA A100 Для обучения использовались HuggingFace Accelerator с Microsoft DeepSpeed (Stage 3) для распределения параметров и стейта оптимизатора, а так же зафьюженный AdamW **GPU часы**: ~240h часов NVIDIA A100 ### Training configuration / Конфигурация обучения **The model was trained using MyLLM framework:** --== [MyLLM](https://github.com/Raumberg/myllm) ==-- **MyLLM Configuration** ```toml [model] model_name_or_path = "attn-signs/watari-32-base-extended" [datasets] dataset = "Vikhrmodels/GrandMaster-PRO-MAX" conversation_field = "conversation" generate_eval_examples = false evaluation_strategy = "steps" eval_steps = 500 dataloader_num_workers = 2 remove_unused_columns = true construct_history = false [run] save_strategy = "steps" save_steps = 500 save_total_limit = 3 run_name = "sft-watari-32" report_to = "wandb" logging_first_step = true logging_steps = 1 output_dir = "models/attn-signs-watari-32" project_name = "sft-lora-watari" resume_from = true [training] train_only_on_completions = false per_device_train_batch_size = 1 per_device_eval_batch_size = 1 num_train_epochs = 1 learning_rate = 0.00004 gradient_accumulation_steps = 8 gradient_checkpointing = true max_seq_length = 32768 warmup_steps = 10 bf16 = true seed = 42 use_peft = true attn_implementation = "flash_attention_2" [lora] lora_target_modules = [ "k_proj", "v_proj", "q_proj", "o_proj", "gate_proj", "up_proj", "down_proj", ] lora_r = 128 lora_alpha = 256 [tokenizer] assistant_message_template = "<|im_start|>assistant" pad_token = "<|endoftext|>" eos_token = "<|im_end|>" chat_template = "{%- if tools %}\n {{- '<|im_start|>system\\n' }}\n {%- if messages[0]['role'] == 'system' %}\n {{- messages[0]['content'] }}\n {%- else %}\n {{- 'Ты Ватари, созданный Attention Signs. Ты умная нейронная сеть, которая старается помочь пользователю во всём.' }}\n {%- endif %}\n {{- \"\\n\\n# Tools\\n\\nТы можешь вызывать специальные функции, чтобы помочь пользователю или выполнить поставленную задачу.\\n\\nТебе доступны сигнатуры функции внутри конструкции XML тэги:\\n\" }}\n {%- for tool in tools %}\n {{- \"\\n\" }}\n {{- tool | tojson }}\n {%- endfor %}\n {{- \"\\n\\n\\nДля каждого вызова функции, верни json объект с именем и аргументами функции внутри конструкции XML тэги:\\n\\n{\\\"name\\\": , \\\"arguments\\\": }\\n<|im_end|>\\n\" }}\n{%- else %}\n {%- if messages[0]['role'] == 'system' %}\n {{- '<|im_start|>system\\n' + messages[0]['content'] + '<|im_end|>\\n' }}\n {%- endif %}\n{%- endif %}\n{%- for message in messages %}\n {%- if (message.role == \"user\") or (message.role == \"system\" and not loop.first) or (message.role == \"assistant\" and not message.tool_calls) %}\n {{- '<|im_start|>' + message.role + '\\n' + message.content + '<|im_end|>' + '\\n' }}\n {%- elif message.role == \"assistant\" %}\n {{- '<|im_start|>' + message.role }}\n {%- if message.content %}\n {{- '\\n' + message.content }}\n {%- endif %}\n {%- for tool_call in message.tool_calls %}\n {%- if tool_call.function is defined %}\n {%- set tool_call = tool_call.function %}\n {%- endif %}\n {{- '\\n\\n{\"name\": \"' }}\n {{- tool_call.name }}\n {{- '\", \"arguments\": ' }}\n {{- tool_call.arguments | tojson }}\n {{- '}\\n' }}\n {%- endfor %}\n {{- '<|im_end|>\\n' }}\n {%- elif message.role == \"tool\" %}\n {%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != \"tool\") %}\n {{- '<|im_start|>user' }}\n {%- endif %}\n {{- '\\n\\n' }}\n {{- message.content }}\n {{- '\\n' }}\n {%- if loop.last or (messages[loop.index0 + 1].role != \"tool\") %}\n {{- '<|im_end|>\\n' }}\n {%- endif %}\n {%- endif %}\n{%- endfor %}\n{%- if add_generation_prompt %}\n {{- '<|im_start|>assistant\\n' }}\n{%- endif %}\n" force_chat_template = true added_special_tokens = [ "<|im_start|>", "<|im_end|>", "<|object_ref_start|>", "<|object_ref_end|>", "<|box_start|>", "<|box_end|>", "<|quad_start|>", "<|quad_end|>", "<|vision_start|>", "<|vision_end|>", "<|vision_pad|>", "<|image_pad|>", "<|video_pad|>" ] ``` ### Using the model / Как запустить? ```python from transformers import AutoTokenizer, AutoModelForCausalLM repo = 'attn-signs/Watari-32b-v0' model = AutoModelForCausalLM.from_pretrained(repo) tokenizer = AutoTokenizer.from_pretrained(repo) model.to('cuda') prompt = 'Расскажи мне про чёрные дыры Керра и сингулярность Белинского — Халатникова — Лифшица (БХЛ-сингулярность). Можешь объяснить это математически?' messages = [ {"role": "system", "content": "Ты Ватари, ассистент и помощник в решении различных задач. Отвечай на вопросы пользователя, рассуждая."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(model.device) generated_ids = model.generate( **model_inputs, max_new_tokens=32768 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) ``` ``` Черные дыры Керра - это вращающиеся черные дыры, описанные математическим решением уравнений общей теории относительности, которое было найдено в 1963 году новозеландским астрономом Роджером Пенроузом и независимо от него Робертом Керром. Черные дыры Керра характеризуются двумя параметрами: массой \( M \) и моментом импульса \( J \). Если момент импульса равен нулю (\( J = 0 \)), то черная дыра становится сферической, как в случае черной дыры Шварцшильда. Математически решение для черных дыр Керра выражается через метрику, которая описывает геометрию пространства-времени вокруг вращающейся массы. Метрика Керра в координатных обозначениях Boyer-Lindquist выглядит следующим образом: \[ ds^2 = -\left(1 - \frac{r_g r}{\Sigma}\right) dt^2 - \frac{2 r_g a r \sin^2 \theta}{\Sigma} dt d\phi + \frac{\Sigma}{\Delta} dr^2 + \Sigma d\theta^2 + \left(r^2 + a^2 + \frac{r_g a^2 r \sin^2 \theta}{\Sigma}\right) \sin^2 \theta d\phi^2 \] где: - \( r_g = \frac{2GM}{c^2} \) - гравитационный радиус, - \( G \) - гравитационная постоянная, - \( M \) - масса черной дыры, - \( c \) - скорость света, - \( a = \frac{J}{Mc} \) - угловый момент на единицу массы, - \( \Sigma = r^2 + a^2 \cos^2 \theta \), - \( \Delta = r^2 - r_g r + a^2 \). Сингулярность Белинского — Халатникова — Лифшица (БХЛ-сингулярность) - это тип пространственной сингулярности, который возникает при определенных условиях во время космологического расширения или сжатия Вселенной. Она характеризуется неодновременным сжатием пространства в разных направлениях, что приводит к образованию "странных" сингулярностей, где некоторые направления сжатия происходят быстрее других. Математическое описание БХЛ-сингулярности включает в себя анализ поведения метрики пространства-времени вблизи такой сингулярности. В общем случае, оно может быть представлено системой уравнений Эйнштейна, которые описывают эволюцию метрических компонент и тензора энергии-импульса материи во времени. Однако точное математическое описание БХЛ-сингулярности требует сложных расчетов и часто рассматривается в рамках численного моделирования. ``` ### Tokenizer research / Исследование токенайзера: You can verify and see the internals of tokenization yourself by the python code provided below: Можно рассмотреть внутренности токенизации самостоятельно, для этого прилагается следующий python код: ```python input_text = "Привет! Я Ватари, интеллектуальный помощник в решении различных задач." # Tokenize tokenized = tokenizer(input_text, return_tensors="pt", return_offsets_mapping=True) tokens = tokenizer.convert_ids_to_tokens(tokenized["input_ids"][0]) # Print raw tokens and decoded versions print("Tokenization Analysis:\n") for i, (token, offset) in enumerate(zip(tokens, tokenized.offset_mapping[0])): # Get start/end positions in original text start, end = offset.tolist() original_slice = input_text[int(start):int(end)] # Clean token representation and replace Ġ (which represent the whitespace) cleaned_token = token.replace('Ġ', ' ').replace('▁', ' ') print(f"Token {i}:") print(f" Raw: {token}") print(f" Cleaned: {cleaned_token}") print(f" Decoded: {tokenizer.decode(tokenized['input_ids'][0][i])}") print(f" Original text slice: '{original_slice}'") print(f" Byte representation: {list(token.encode('utf-8'))}") print("-" * 50) # Verify full reconstruction print("\nFull Reconstruction:", tokenizer.decode(tokenized["input_ids"][0])) ``` **Output / Результат:** ``` ... -------------------------------------------------- Token 8: Raw: ĠинÑĤеллекÑĤ Cleaned: инÑĤеллекÑĤ Decoded: интеллект Original text slice: ' интеллект' Byte representation: [196, 160, 195, 144, 194, 184, 195, 144, 194, 189, 195, 145, 196, 164, 195, 144, 194, 181, 195, 144, 194, 187, 195, 144, 194, 187, 195, 144, 194, 181, 195, 144, 194, 186, 195, 145, 196, 164] -------------------------------------------------- Token 9: Raw: Ñĥ Cleaned: Ñĥ Decoded: у Original text slice: 'у' Byte representation: [195, 145, 196, 165] ... Token 13: Raw: ĠÑĢеÑĪении Cleaned: ÑĢеÑĪении Decoded: решении Original text slice: ' решении' Byte representation: [196, 160, 195, 145, 196, 162, 195, 144, 194, 181, 195, 145, 196, 170, 195, 144, 194, 181, 195, 144, 194, 189, 195, 144, 194, 184, 195, 144, 194, 184] -------------------------------------------------- Token 14: Raw: ĠÑĢазлиÑĩнÑĭÑħ Cleaned: ÑĢазлиÑĩнÑĭÑħ Decoded: различных Original text slice: ' различных' Byte representation: [196, 160, 195, 145, 196, 162, 195, 144, 194, 176, 195, 144, 194, 183, 195, 144, 194, 187, 195, 144, 194, 184, 195, 145, 196, 169, 195, 144, 194, 189, 195, 145, 196, 173, 195, 145, 196, 167] -------------------------------------------------- Full Reconstruction: Привет! Я Ватари, интеллектуальный помощник в решении различных задач. ```