File size: 9,460 Bytes
541e495
52e90df
 
 
 
 
 
 
 
 
 
 
541e495
 
deffc28
541e495
c8519fc
541e495
52e90df
541e495
13f8cff
 
ae16f3f
f545560
52e90df
 
 
 
 
 
5ef77b9
 
52e90df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13f8cff
52e90df
 
 
 
13f8cff
 
 
 
 
 
 
 
 
 
 
 
52e90df
 
 
 
 
 
 
ff82758
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
---
datasets:
- IlyaGusev/ru_turbo_alpaca
- IlyaGusev/ru_turbo_saiga
- IlyaGusev/ru_sharegpt_cleaned
- IlyaGusev/oasst1_ru_main_branch
- IlyaGusev/ru_turbo_alpaca_evol_instruct
- lksy/ru_instruct_gpt4
language:
- ru
pipeline_tag: conversational
license: cc-by-4.0
---

# Saiga2 7B, Russian LLaMA2-based chatbot

Based on [LLaMA-2 13B HF](https://huggingface.co/meta-llama/Llama-2-13b-hf).

This is an adapter-only version.

Colab: [link](https://colab.research.google.com/drive/16xn7Zi2jli_9iPuKeM9wx53wkouzBQIf)

Llama.cpp version: [link](https://huggingface.co/IlyaGusev/saiga2_13b_ggml)

Training code: [link](https://github.com/IlyaGusev/rulm/tree/master/self_instruct)

**WARNING 1**: Run with the development version of `transformers` and `peft`!

**WARNING 2**: Avoid using V100 (in Colab, for example). Outputs are much worse in this case.

**WARNING 3**: You can use the [Llama-2-13B-fp16](https://huggingface.co/TheBloke/Llama-2-13B-fp16) base model instead.

```python
from peft import PeftModel, PeftConfig
from transformers import AutoModelForCausalLM, AutoTokenizer, GenerationConfig

MODEL_NAME = "IlyaGusev/saiga2_13b_lora"
DEFAULT_MESSAGE_TEMPLATE = "<s>{role}\n{content}</s>\n"
DEFAULT_SYSTEM_PROMPT = "Ты — Сайга, русскоязычный автоматический ассистент. Ты разговариваешь с людьми и помогаешь им."

class Conversation:
    def __init__(
        self,
        message_template=DEFAULT_MESSAGE_TEMPLATE,
        system_prompt=DEFAULT_SYSTEM_PROMPT,
        start_token_id=1,
        bot_token_id=9225
    ):
        self.message_template = message_template
        self.start_token_id = start_token_id
        self.bot_token_id = bot_token_id
        self.messages = [{
            "role": "system",
            "content": system_prompt
        }]

    def get_start_token_id(self):
        return self.start_token_id

    def get_bot_token_id(self):
        return self.bot_token_id

    def add_user_message(self, message):
        self.messages.append({
            "role": "user",
            "content": message
        })

    def add_bot_message(self, message):
        self.messages.append({
            "role": "bot",
            "content": message
        })

    def get_prompt(self, tokenizer):
        final_text = ""
        for message in self.messages:
            message_text = self.message_template.format(**message)
            final_text += message_text
        final_text += tokenizer.decode([self.start_token_id, self.bot_token_id])
        return final_text.strip()


def generate(model, tokenizer, prompt, generation_config):
    data = tokenizer(prompt, return_tensors="pt")
    data = {k: v.to(model.device) for k, v in data.items()}
    output_ids = model.generate(
        **data,
        generation_config=generation_config
    )[0]
    output_ids = output_ids[len(data["input_ids"][0]):]
    output = tokenizer.decode(output_ids, skip_special_tokens=True)
    return output.strip()

config = PeftConfig.from_pretrained(MODEL_NAME)
model = AutoModelForCausalLM.from_pretrained(
    config.base_model_name_or_path,
    load_in_8bit=True,
    torch_dtype=torch.float16,
    device_map="auto"
)
model = PeftModel.from_pretrained(
    model,
    MODEL_NAME,
    torch_dtype=torch.float16
)
model.eval()

tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, use_fast=False)
generation_config = GenerationConfig.from_pretrained(MODEL_NAME)
print(generation_config)

inputs = ["Почему трава зеленая?", "Сочини длинный рассказ, обязательно упоминая следующие объекты. Дано: Таня, мяч"]
for inp in inputs:
    conversation = Conversation()
    conversation.add_user_message(inp)
    prompt = conversation.get_prompt(tokenizer)

    output = generate(model, tokenizer, prompt, generation_config)
    print(inp)
    print(output)
    print()
    print("==============================")
    print()
```

Examples:
```
User: Почему трава зеленая? 
Saiga: Зеленый цвет растений обусловлен наличием пигмента хлорофилла в их листьях. Хлорофилл содержит железо, которое способно поглощать световой волны красного, оранжевого и желтого цвета, а отражает световые волны зеленого цвета. Таким образом, зеленый цвет является результатом процесса фотосинтеза, который происходит в листьях растений.
```

```
User: Сочини длинный рассказ, обязательно упоминая следующие объекты. Дано: Таня, мяч
Saiga: Однажды в парке на улице Ленина произошло невероятное событие. В тот день, когда все жители города были заняты своими делами, Таня решила отправиться на прогулку. Она была очень веселой и радостной, потому что еще накануне она получила отличные оценки за успешную защиту курсовой работы.
Перед тем как выйти из дома, Тане пришла идея взять с собой мяч для игры в футбол. Она знала, что в парке есть хорошая площадка для этого вида спорта, поэтому решила воспользоваться этим прекрасным временем.
Когда Таня подошла к парку, она заметила множество людей, которые играли в различные виды спорта. Некоторые стояли у столов для настольного тенниса, другие – на кортах для баскетбола или волейбола. Но ни один из них не был занят футболом.
Так как Тане было очень хотелось сыграть в футбол, она решила начать самостоятельную игру. Она бросила мяч в воздух и стала бегать за ним, пытаясь его достать. Однако, каждый раз, когда она подбиралась к мячу, он быстро летел далеко от нее.
Вскоре к Тане подошел молодой парень, который также играл в футбол. Он предложил ей стать её партнером и помочь ей в игре. Тане была рада этому предложению, так как она не могла играть одна.
Игра продолжалась уже несколько часов. Молодой парень и Таня перемещались по всей площадке, стараясь забить голы друг другу. Их команды менялись каждый раз, когда они забивали мяч в противоположные ворота.
Но внезапно, когда Тане думала, что игра уже закончена, она заметила, что мяч исчез. Она и ее партнер начали искать его по всей площадке, но никаких следов не находили.
Наконец, после долгого поисков, Тане заметила, что мяч находится в глубине кустов. Она и ее партнер решили проникнуть внутрь, чтобы найти его.
Через некоторое время они нашли мяч, который был спрятан в густом кусте. Когда они выбрались из него, они обнаружили, что их путь ведет к большому дереву.
Дерево было очень высоким и красивым, и Тане сразу же поняла, что это было место, где она должна остаться. Она решила, что будет здесь играть в футбол каждую субботу вместе со своим новым партнером.
Так произошло, что благодаря этой случайной встрече, Тане нашла своего нового друга и новое увлечение. С тех пор она проводила каждую субботу в этом парке, играя в футбол и наслаждаясь прекрасными видами.

```

v1:
- dataset code revision 7712a061d993f61c49b1e2d992e893c48acb3a87
- wandb [link](https://wandb.ai/ilyagusev/rulm_self_instruct/runs/848s9kbi)
- 7 datasets: ru_turbo_alpaca, ru_turbo_saiga, ru_sharegpt_cleaned, oasst1_ru_main_branch, gpt_roleplay_realm, ru_turbo_alpaca_evol_instruct (iteration 1/2), ru_instruct_gpt4
- Datasets merging script: [create_chat_set.py](https://github.com/IlyaGusev/rulm/blob/e4238fd9a196405b566a2d5838ab44b7a0f4dc31/self_instruct/src/data_processing/create_chat_set.py)
- saiga2_13b vs saiga13b: 79-2-95