diff --git a/docs/docs/data/datasets.md b/docs/docs/data/datasets.md index e1dfc08d..31882a04 100644 --- a/docs/docs/data/datasets.md +++ b/docs/docs/data/datasets.md @@ -37,17 +37,16 @@ for stability**. ### 1. **Fork the OpenAssistant repository** -Fork the -`OpenAssistant`[repository](https://github.com/LAION-AI/Open-Assistant). To do -this, click the link to the repository and click "Fork" in the upper-right +Fork the [OpenAssistant repository](https://github.com/LAION-AI/Open-Assistant). +To do this, click the link to the repository and click "Fork" in the upper-right corner. You should get an option to fork to your account, provided you are signed into Github. After you fork, clone the repository locally. You can do so as follows: ```bash -git clone git@github.com:/OpenAssistant.git -cd OpenAssistant # enter the directory +git clone git@github.com:/Open-Assistant.git +cd Open-Assistant # enter the directory ``` Next, you want to set your `upstream` location to enable you to push/pull (add @@ -76,7 +75,7 @@ upstream git@github.com:LAION-AI/Open-Assistant.git (push) If you do NOT have an `origin` for whatever reason, then run: ```bash -git remote add origin git@github.com:/OpenAssistant.git +git remote add origin git@github.com:/Open-Assistant.git ``` The goal of `upstream` is to keep your repository up-to-date to any changes that @@ -100,7 +99,7 @@ git checkout -b :::caution -Please do not make changes on the master branch! +Please do not make changes on the main branch! ::: @@ -114,7 +113,7 @@ The correct branch will have a asterisk \* in front of it. ### 2. **Create a development environment** -You can make an environment in any way you choose to. We highlight two possible +You can make an environment in any way you choose. We highlight two possible options: #### 2a) Create a conda environment diff --git a/docs/docs/data/supervised-datasets.md b/docs/docs/data/supervised-datasets.md index f74ead26..450a8c87 100644 --- a/docs/docs/data/supervised-datasets.md +++ b/docs/docs/data/supervised-datasets.md @@ -6,7 +6,7 @@ For discussion about usage of supervised data see issue ## Motivation An important part of making the assistant useful is to teach it to understand -and follow instructions, and to perform large set of tasks well. +and follow instructions, and to perform a large set of tasks well. While RLHF seems like the main ingredient, using existing supervised data might help. diff --git a/docs/docs/faq/faq.md b/docs/docs/faq/faq.md index fdd03688..86f4a161 100644 --- a/docs/docs/faq/faq.md +++ b/docs/docs/faq/faq.md @@ -61,7 +61,7 @@ website [https://open-assistant.io/](https://open-assistant.io/). If you want to contribute code, take a look at the [tasks in GitHub](https://github.com/orgs/LAION-AI/projects/3) and grab one. Take a look at this -[contributing guide](https://github.com/GuilleHoardings/Open-Assistant/blob/main/CONTRIBUTING.md). +[contributing guide](https://github.com/LAION-AI/Open-Assistant/blob/main/CONTRIBUTING.md). ## Questions about the model training website diff --git a/model/reward/instructor/rank_datasets.py b/model/reward/instructor/rank_datasets.py index 545f6269..81b6d08a 100644 --- a/model/reward/instructor/rank_datasets.py +++ b/model/reward/instructor/rank_datasets.py @@ -18,6 +18,7 @@ """ +import os from dataclasses import dataclass from typing import Dict, List, Optional, Union @@ -298,3 +299,44 @@ class AnthropicRLHF(Dataset): context, pair = self.pairs[index] return context, [pair] + + +class OAPrivate(Dataset): + """ + { + "prompt": , + "history": [("prompt1", "answer2"), ("prompt2", "answer2")], + "pos": , + "neg_replies": [list of bad answers] + } + """ + + split_name_mapping = { + "train": "rm_train.jsonl", + "test": "rm_test.jsonl", + "val": "rm_val.jsonl", + } + + def __init__(self, split="train", sep_token="", data_path=".cache") -> None: + super().__init__() + import json + + jsonl_file = os.path.join(data_path, self.split_name_mapping[split]) + self.pairs = [] + with open(jsonl_file, "r", encoding="utf-8") as f: + for line in f: + data = json.loads(line) + prefix = sep_token.join([sep_token.join(p) for p in data["history"][-2:]]) + prefix += sep_token + data["prompt"] + pair = [] + for neg_text in data["neg_replies"]: + pair.append((data["pos"], neg_text)) + self.pairs.append((prefix, pair)) + + def __len__(self): + return len(self.pairs) + + def __getitem__(self, index): + context, pair = self.pairs[index] + + return context, pair diff --git a/model/reward/instructor/utils.py b/model/reward/instructor/utils.py index 94a256c2..2e235213 100644 --- a/model/reward/instructor/utils.py +++ b/model/reward/instructor/utils.py @@ -115,7 +115,7 @@ def argument_parsing(parser): def get_datasets(dataset_list: List[AnyStr], tokenizer): - from rank_datasets import AnthropicRLHF, GPTJSynthetic, HFSummary, WebGPT + from rank_datasets import AnthropicRLHF, GPTJSynthetic, HFSummary, OAPrivate, WebGPT from torch.utils.data import ConcatDataset train_datasets, evals = [], {} @@ -141,5 +141,11 @@ def get_datasets(dataset_list: List[AnyStr], tokenizer): eval = AnthropicRLHF("test", tokenizer.sep_token) train_datasets.append(train) evals["anthropic_rlhf"] = eval + elif "oa_private" == dataset_name: + train = OAPrivate(split="train", sep_token=tokenizer.sep_token) + eval = OAPrivate(split="val", sep_token=tokenizer.sep_token) + train_datasets.append(train) + evals["oa_private"] = eval + train = ConcatDataset(train_datasets) return train, evals diff --git a/model/supervised_finetuning/custom_datasets/__init__.py b/model/supervised_finetuning/custom_datasets/__init__.py index ee061f04..0e5b9a91 100644 --- a/model/supervised_finetuning/custom_datasets/__init__.py +++ b/model/supervised_finetuning/custom_datasets/__init__.py @@ -1,8 +1,8 @@ """ High level functions for model training """ -from custom_datasets.prompt_dialogue import InstructionTuning, PromptGeneratedDataset -from custom_datasets.qa_datasets import SODA, JokeExplaination, QADataset, SODADialogue, WebGPT +from custom_datasets.prompt_dialogue import InstructionTuning, PrivateInstructionTuning, PromptGeneratedDataset +from custom_datasets.qa_datasets import SODA, JokeExplaination, QADataset, SODADialogue, TranslatedQA, WebGPT from custom_datasets.summarization import SummarizationDataset from custom_datasets.toxic_conversation import ProsocialDialogue, ProsocialDialogueExplaination from custom_datasets.translation import WMT2019, DiveMT, TEDTalk @@ -32,7 +32,7 @@ SUMMARIZATION_DATASETS = [ "debate_sum", "tldr_news", ] -OTHER = ["prosocial_dialogue", "explain_prosocial", "instruct_tuning"] +OTHER = ["prosocial_dialogue", "explain_prosocial", "instruct_tuning", "private_tuning", "oa_translated"] def train_val_dataset(dataset, val_split=0.2): @@ -92,6 +92,12 @@ def get_one_dataset(conf, dataset_name): elif dataset_name == "instruct_tuning": dataset = InstructionTuning(conf.cache_dir) train, eval = train_val_dataset(dataset, val_split=0.2) + elif dataset_name == "private_tuning": + dataset = PrivateInstructionTuning(conf.cache_dir) + train, eval = train_val_dataset(dataset, val_split=0.2) + elif dataset_name == "oa_translated": + dataset = TranslatedQA(conf.cache_dir) + train, eval = train_val_dataset(dataset, val_split=0.01) else: raise ValueError(f"Unknown dataset {dataset_name}") diff --git a/model/supervised_finetuning/custom_datasets/dialogue_collator.py b/model/supervised_finetuning/custom_datasets/dialogue_collator.py index c96ed576..0a0b7a5a 100644 --- a/model/supervised_finetuning/custom_datasets/dialogue_collator.py +++ b/model/supervised_finetuning/custom_datasets/dialogue_collator.py @@ -1,3 +1,4 @@ +import random from dataclasses import dataclass from typing import Optional, Union @@ -76,3 +77,108 @@ class DialogueDataCollator: batch["targets"] = torch.roll(batch["input_ids"], -1, -1) return batch + + +@dataclass +class TrainDialogueDataCollator: + """ + Expects a list of texts corresponding to a sequence of [question, answer, question, answer, ...] pairs. + """ + + tokenizer: PreTrainedTokenizerBase + padding: Union[bool, str, PaddingStrategy] = True + max_length: Optional[int] = None + mix_length_threshold: Optional[int] = 256 + mix_probability: Optional[int] = 0.6 + pad_to_multiple_of: Optional[int] = None + + def __call__(self, features): + flatten_messages = [] + label_masks = [] + total_short_context = 0 + for messages in features: + messages = list(messages) + + # Add a way for the model to terminate generation + # When we predict the start of a new expected question, we want to be able to stop generation + messages.append(self.tokenizer.eos_token) + + flatten_message = self.tokenizer( + "".join(messages), + truncation=True, + max_length=self.max_length, + return_offsets_mapping=True, + ) + + message_change_indices = np.cumsum([len(x) for x in messages[:-1]]) + # for each token an integer indicating the index of the message it belongs to. Just to create the label mask. + # Label mask is true when predicting a token that is part of the answer, false otherwise. + # TEXT: Question: Hello, how are you? Answer: I am fine. Question: What is your name? Answer: My name is John. Question: + # MESSAGE_INDICES: 0 0 0 0 0 0 1 1 1 2 2 2 2 2 2 3 3 3 3 -2 + # LABEL_MASK: 0 0 0 0 0 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 + + # If no result in next, we are predicting the last termination token(s) + message_indices = list( + map( + lambda x: next((i for i, val in enumerate(message_change_indices) if val >= x), -2), + list(map(lambda x: x[1], flatten_message["offset_mapping"])), + ) + ) + label_mask = np.roll(list(map(lambda x: x % 2 == 1, message_indices)), -1, -1) + try: + label_mask[[i for i in range(len(message_indices)) if message_indices[i] == -2][0] - 1] = True + except IndexError: + # due to truncation, we might not have the last termination token + label_mask[-1] = False + + label_masks.append(label_mask) + if len(flatten_message["input_ids"]) < self.mix_length_threshold: + total_short_context += len(flatten_message["input_ids"]) + flatten_messages.append({k: v for k, v in flatten_message.items() if k != "offset_mapping"}) + # packing + if total_short_context > 2: + _flatten_messages, _label_masks = [], [] + prev_short_msg, prev_short_mask = None, None + for flatten_msg, label_mask in zip(flatten_messages, label_masks): + if len(flatten_msg["input_ids"]) < self.mix_length_threshold and random.random() > 0.6: + if prev_short_msg is not None: + for key in flatten_msg.keys(): + flatten_msg[key] += prev_short_msg[key] + flatten_msg[key] = flatten_msg[key][: self.max_length] + label_mask = np.concatenate([label_mask, prev_short_mask]) + _label_masks.append(label_mask[: self.max_length]) + _flatten_messages.append(flatten_msg) + # reset + prev_short_msg, prev_short_mask = None, None + else: + # prime + prev_short_msg, prev_short_mask = flatten_msg, label_mask + else: + _label_masks.append(label_mask) + _flatten_messages.append(flatten_msg) + if prev_short_msg is not None: + for key in flatten_msg.keys(): + flatten_msg[key] += prev_short_msg[key] + flatten_msg[key] = flatten_msg[key][: self.max_length] + label_mask = np.concatenate([label_mask, prev_short_mask])[: self.max_length] + _label_masks.append(label_mask) + _flatten_messages.append(flatten_msg) + + label_masks = _label_masks + flatten_messages = _flatten_messages + + batch = self.tokenizer.pad( + flatten_messages, + padding=self.padding, + max_length=self.max_length, + pad_to_multiple_of=self.pad_to_multiple_of, + return_tensors="pt", + ) + dim = batch["input_ids"].shape[-1] + + batch["label_masks"] = torch.stack( + [F.pad(torch.tensor(x), (0, dim - len(x)), value=False) for x in label_masks] + ) + batch["targets"] = torch.roll(batch["input_ids"], -1, -1) + + return batch diff --git a/model/supervised_finetuning/custom_datasets/prompt_dialogue.py b/model/supervised_finetuning/custom_datasets/prompt_dialogue.py index 1c823934..4aac2655 100644 --- a/model/supervised_finetuning/custom_datasets/prompt_dialogue.py +++ b/model/supervised_finetuning/custom_datasets/prompt_dialogue.py @@ -2,7 +2,7 @@ import json import os from urllib.request import urlopen -from custom_datasets.formatting import format_pair +from custom_datasets.formatting import QA_SPECIAL_TOKENS, format_pair from torch.utils.data import Dataset @@ -102,3 +102,45 @@ class InstructionTuning(Dataset): def __getitem__(self, index): return format_pair(self.pairs[index]) + + +class PrivateInstructionTuning(Dataset): + """ + We have seen some promising capabilities from instruction tuning + with the following mix of datasets that are derived from datasets + available online. + The files for this data are in json format as a list of tuples + where each tuple is (source,instruction_response_pair) + + Not to be confused with unatural instruction + """ + + name = "private_tuning" + filename = "oa_v3_fixed_plus_safety.jsonl" + + def __init__(self, cache_dir) -> None: + super().__init__() + os.makedirs(cache_dir, exist_ok=True) + + self.pairs = [] + for file_link in [self.filename]: + basename = file_link.split("/")[-1] + instruction_tune_file = os.path.join(cache_dir, basename) + + with open(instruction_tune_file, "r", encoding="utf-8") as f: + for line in f: + row = json.loads(line) + prefix = "" + for _, convo in enumerate(row["text"].split("User:")): + if "Assistant" in convo: + prompt, answer = convo.split("Assistant:", maxsplit=1) + answer = answer.replace("<|endoftext|>", "").strip() + self.pairs.append((prefix + QA_SPECIAL_TOKENS["Question"] + prompt, answer)) + prefix += "".join(format_pair((prompt, answer))) + + def __len__(self): + return len(self.pairs) + + def __getitem__(self, index): + prompt, answer = self.pairs[index] + return "{}{}".format(prompt, QA_SPECIAL_TOKENS["Answer"]), answer diff --git a/model/supervised_finetuning/custom_datasets/qa_datasets.py b/model/supervised_finetuning/custom_datasets/qa_datasets.py index 092b7743..f126a270 100644 --- a/model/supervised_finetuning/custom_datasets/qa_datasets.py +++ b/model/supervised_finetuning/custom_datasets/qa_datasets.py @@ -1,6 +1,7 @@ """ Open / close book QA datasets """ +import glob import json import os import re @@ -137,11 +138,13 @@ class QADataset(Dataset): self.dataset = load_dataset(context["name"], **context["params"]) else: raise ValueError("Unknown dataset : " + dataset) + self.length = len(self.dataset) def __len__(self): - return len(self.dataset) + return self.length def __getitem__(self, idx): + data = self.dataset[idx] return format_pair(self.index_fn(data)) @@ -311,14 +314,75 @@ class JokeExplaination(Dataset): for line in f: data = json.loads(line) joke = data["joke"] - explanation = data["explanation"] + # DO NOT change this + # its the data that had syntax error + explanation = data["explaination"] self.pairs.append((joke, explanation)) if len(question) > 0 and len(answer) > 0: self.pairs.append((question, answer)) + self.length = len(self.pairs) def __len__(self): - return len(self.pairs) + return self.length def __getitem__(self, index): return format_pair(self.pairs[index]) + + +class TranslatedQA(Dataset): + """ + Translation OA v3 results + a list of non english translation of OA v3 instruction generated text in jsonl + format for each line: + { + "text": "User: ... Assistant: ....", + "meta": {"source": ... }, + "translate": [ + { "round": 1, "human":"...", "answer": "..."}, + ... + { "round": K, "human":"...", "answer": "..."}, + ] + } + Since OA contain some code we needed to reference the original text to skip these + """ + + name = "oa_translated" + + def __init__(self, cache_dir) -> None: + super().__init__() + os.makedirs(cache_dir, exist_ok=True) + path = os.path.join(cache_dir, self.name) + os.makedirs(path, exist_ok=True) + self.pairs = [] + for translated_jsonl in glob.glob(os.path.join(path, "*.jsonl")): + with open(translated_jsonl, "r") as fin: + for line in fin: + data = json.loads(line) + if "Python " in data["text"]: + # translation currently doesn't ignore code + # so we will have to reference original text + # for ignoring the translation + continue + prefix = "" + for convo_round in data["translate"]: + human, answer = format_pair((convo_round["human"], convo_round["answer"])) + if convo_round["round"] > 2: + self.pairs.append(("{}{}{}".format(prefix, "", human), answer)) + else: + self.pairs.append((human, answer)) + + prefix += "{}{}{}{}".format( + QA_SPECIAL_TOKENS["Question"], + convo_round["human"], + QA_SPECIAL_TOKENS["Answer"], + convo_round["answer"], + ) + + self.length = len(self.pairs) + + def __len__(self): + return self.length + + def __getitem__(self, index): + return self.pairs[index] diff --git a/model/supervised_finetuning/custom_datasets/summarization.py b/model/supervised_finetuning/custom_datasets/summarization.py index 834fa16c..aa644691 100644 --- a/model/supervised_finetuning/custom_datasets/summarization.py +++ b/model/supervised_finetuning/custom_datasets/summarization.py @@ -57,7 +57,7 @@ def index_summary_merge(text, summary): class SummarizationDataset(Dataset): def __init__(self, dataset, cache_dir, split, max_words=512): self.name = dataset - if summarization_config_mapping[dataset][0] in ["billsum", "tldr_news"] & split == "validation": + if (dataset in ["billsum", "tldr_news"]) and (split == "validation"): split = "test" self.dataset = load_dataset(*summarization_config_mapping[dataset], cache_dir=cache_dir, split=split) self.text_column, self.summary_column = summarization_name_mapping[dataset] diff --git a/model/supervised_finetuning/custom_datasets/translation.py b/model/supervised_finetuning/custom_datasets/translation.py index 008de751..cece0b43 100644 --- a/model/supervised_finetuning/custom_datasets/translation.py +++ b/model/supervised_finetuning/custom_datasets/translation.py @@ -62,7 +62,8 @@ TRANSLATION_PROMPT = { "{} how do we write in Malay", "{} give me the malay translation", "{} , berikan saya terjemahan dalam bahasa melayu", - "{}, Jemahan di bahasa melayu" "{}, jemahkan ayat ini kepada bahasa melayu", + "{}, Jemahan di bahasa melayu", + "{}, jemahkan ayat ini kepada bahasa melayu", ], "en": ["{}. translate to english", "{} write in english", "english translation: '{}'"], "ru": ["помогите мне перевести это на русский : {}", "{} перевести на русский язык", "russian translation: '{}'"], @@ -71,24 +72,40 @@ TRANSLATION_PROMPT = { "nl": ["{}. translate to dutch", "{} write in dutch", "dutch translation: '{}'"], "vi": ["{}. Dịch sang tiếng việt nam", "{} write in vietnamese", "vietnamese translation: '{}'"], "ar": ["{}. translate to arabic", "{} write in arabic", "arabic translation: '{}'"], + "es": ["{}. translate to spanish", "{} write in spanish", "spanish translation: '{}'"], + "hi": ["{}. translate to hindi", "{}. translate to bengali", "{} write in hindi", "bengali translation: '{}'"], } class TranslationPair(Dataset): - def __init__(self) -> None: + def __init__(self, mix_prob=0.2) -> None: super().__init__() self.pairs = [] + self.length = -1 + self.mix_prob = mix_prob def __len__(self): + if self.length < 0: + self.length = len(self.pairs) return len(self.pairs) def __getitem__(self, index): + if random.random() < self.mix_prob and index > 5 and index < (self.length - 5): + additional = random.randint(0, 10) - 5 + while additional == index: + additional = random.randint(0, 10) - 5 + + history_text = "".join(format_pair(self.pairs[additional + index])) + question, answer = self.pairs[index] + question = history_text + question + return format_pair((question, answer)) + return format_pair(self.pairs[index]) class WMT2019(TranslationPair): - def __init__(self, pair="zh-en", split="train") -> None: - super().__init__() + def __init__(self, pair="zh-en", split="train", mix_prob=0.2) -> None: + super().__init__(mix_prob=mix_prob) dataset = load_dataset("wmt19", pair)[split] self.pairs = [] src, tgt = pair.split("-") @@ -106,8 +123,8 @@ class DiveMT(TranslationPair): REMAP = {"tur": "tr", "ita": "it", "ukr": "uk", "nld": "nl", "vie": "vi", "ara": "ar"} - def __init__(self, split="train") -> None: - super().__init__() + def __init__(self, split="train", mix_prob=0.2) -> None: + super().__init__(mix_prob=mix_prob) dataset = load_dataset("GroNLP/divemt", "main")[split] tgt, src = "tgt_text", "src_text" for row in dataset: @@ -129,8 +146,8 @@ class DiveMT(TranslationPair): class TEDTalk(TranslationPair): # NOTE: DO NOT use chinese pair, mix with traditional and cantonese, not clean - def __init__(self, pair="de-ja", split="train", year="2016") -> None: - super().__init__() + def __init__(self, pair="de-ja", split="train", year="2016", mix_prob=0.2) -> None: + super().__init__(mix_prob=mix_prob) dataset = load_dataset("ted_talks_iwslt", language_pair=pair.split("-"), year=year)[split] src, tgt = pair.split("-") for row in dataset: diff --git a/model/supervised_finetuning/tests/test_datasets.py b/model/supervised_finetuning/tests/test_datasets.py index 8d5ad08f..2a0d4481 100644 --- a/model/supervised_finetuning/tests/test_datasets.py +++ b/model/supervised_finetuning/tests/test_datasets.py @@ -27,7 +27,7 @@ def test_collate_fn(): config = Namespace(cache_dir=".cache", model_name="Salesforce/codegen-2B-multi") tokenizer = get_tokenizer(config) - collate_fn = DialogueDataCollator(tokenizer, max_length=512) + collate_fn = DialogueDataCollator(tokenizer, max_length=620) qa_base = QA_DATASETS summarize_base = SUMMARIZATION_DATASETS others = ["prompt_dialogue", "webgpt", "soda", "joke", "gsm8k"] @@ -40,11 +40,14 @@ def test_collate_fn(): dataloader = DataLoader(ConcatDataset(trains), collate_fn=collate_fn, batch_size=128) for batch in dataloader: - print(batch.keys()) + print(batch["targets"].shape[0]) print(tokenizer.decode(batch["input_ids"][0])) print("-----") print(tokenizer.decode(batch["targets"][0][batch["label_masks"][0]])) - assert batch["targets"].shape[1] <= 512 + assert batch["targets"].shape[1] <= 620 dataloader = DataLoader(ConcatDataset(evals), collate_fn=collate_fn, batch_size=128) for batch in dataloader: - assert batch["targets"].shape[1] <= 512 + assert batch["targets"].shape[1] <= 620 + + +test_collate_fn() diff --git a/model/supervised_finetuning/trainer.py b/model/supervised_finetuning/trainer.py index fb5d4bee..ce80830b 100644 --- a/model/supervised_finetuning/trainer.py +++ b/model/supervised_finetuning/trainer.py @@ -1,14 +1,19 @@ import argparse from distutils.util import strtobool from functools import partial -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Dict, List, Optional, Tuple, Union import bitsandbytes +import datasets import torch from efficiency_utils import fuse_gelu from torch import nn +from torch.utils.data import DataLoader from transformers import PreTrainedModel, Trainer, TrainingArguments +from transformers.trainer_pt_utils import IterableDatasetShard +from transformers.trainer_utils import seed_worker from transformers.training_args import OptimizerNames +from transformers.utils import is_datasets_available from utils import PerDatasetSampler, get_dataset, get_loss, get_metrics, get_model, get_tokenizer, read_yamls @@ -34,10 +39,11 @@ class SFTTrainer(Trainer): sampler: torch.utils.data.sampler.Sampler = None, loss_function: str = "CrossEntropyLoss", poly_eps: float = 1.0, + train_collate_fn: Callable = None, **kwargs, ): super().__init__(model, args, **kwargs) - + self.train_collate_fn = train_collate_fn # By default CrossEntropyLoss ignores padding_index -100, but just in case use our own loss_fct self.loss_fct = get_loss(loss_function, poly_eps) self.sampler = sampler @@ -92,30 +98,51 @@ class SFTTrainer(Trainer): return (loss, logits, labels) def get_train_dataloader(self): - """Inject custom data sampling behaviour into training loop""" - if self.sampler is None: - torch.utils.data.DataLoader( - self.train_dataset, - batch_size=self.args.per_device_train_batch_size, - shuffle=True, - collate_fn=self.data_collator, - ) - else: - dataloader = torch.utils.data.DataLoader( - self.train_dataset, - batch_size=self.args.per_device_train_batch_size, - sampler=self.sampler, - collate_fn=self.data_collator, - ) - if torch.cuda.device_count() <= 1: - return dataloader - else: - # Not strictly necessary to use accelerate, currently just - # ensures batches are padded to be divisible by # devices - from accelerate import Accelerator + """ + Inject custom data sampling behaviour into training loop + and use custom task mixing collate function : train_collate_fn - accelerator = Accelerator() - return accelerator.prepare(dataloader) + rewrite from: + https://github.com/huggingface/transformers/blob/67d074874d285e616393c65a0e670088e1b6b74a/src/transformers/trainer.py#L846 + """ + data_collator = self.train_collate_fn + train_dataset = self.train_dataset + if is_datasets_available() and isinstance(train_dataset, datasets.Dataset): + train_dataset = self._remove_unused_columns(train_dataset, description="training") + + if isinstance(train_dataset, torch.utils.data.IterableDataset): + # if we are using iterable dataset it means no weight sampling + # added for backward compat + if self.args.world_size > 1: + train_dataset = IterableDatasetShard( + train_dataset, + batch_size=self._train_batch_size, + drop_last=self.args.dataloader_drop_last, + num_processes=self.args.world_size, + process_index=self.args.process_index, + ) + return DataLoader( + train_dataset, + batch_size=self.args.per_device_train_batch_size, + collate_fn=data_collator, + num_workers=self.args.dataloader_num_workers, + pin_memory=self.args.dataloader_pin_memory, + ) + if self.sampler is None: + train_sampler = self._get_train_sampler() + else: + train_sampler = self.sampler + + return DataLoader( + train_dataset, + batch_size=self._train_batch_size, + sampler=train_sampler, + collate_fn=data_collator, + drop_last=self.args.dataloader_drop_last, + num_workers=self.args.dataloader_num_workers, + pin_memory=self.args.dataloader_pin_memory, + worker_init_fn=seed_worker, + ) def _strtobool(x): @@ -168,8 +195,7 @@ if __name__ == "__main__": tokenizer = get_tokenizer(training_conf) model = get_model(training_conf, tokenizer) - - train, evals, collate_fn = get_dataset(training_conf, tokenizer) + train, evals, collate_fn, train_collate_fn = get_dataset(training_conf, tokenizer) sampler = PerDatasetSampler.build_sampler_from_config(training_conf, train.datasets) metrics, preprocess_fns = get_metrics(training_conf, tokenizer) optimizer = OptimizerNames.ADAMW_BNB if training_conf.quantization else OptimizerNames.ADAMW_HF @@ -222,6 +248,7 @@ if __name__ == "__main__": model=model, args=args, sampler=sampler, + train_collate_fn=train_collate_fn, loss_function=training_conf.loss_fn, poly_eps=training_conf.poly_eps, train_dataset=train, diff --git a/model/supervised_finetuning/utils.py b/model/supervised_finetuning/utils.py index 1f77708f..43377bc9 100644 --- a/model/supervised_finetuning/utils.py +++ b/model/supervised_finetuning/utils.py @@ -6,7 +6,7 @@ import evaluate import transformers import yaml from custom_datasets import get_one_dataset -from custom_datasets.dialogue_collator import DialogueDataCollator +from custom_datasets.dialogue_collator import DialogueDataCollator, TrainDialogueDataCollator from custom_datasets.qa_datasets import QA_SPECIAL_TOKENS from losses import CrossEntropyLoss, PolyLoss from models import freeze_top_n_layers, get_specific_model @@ -126,7 +126,14 @@ def get_tokenizer(conf) -> transformers.AutoTokenizer: if tokenizer_config.special_tokens: if "GPT-JT" in conf.model_name: tokenizer_config.special_tokens.pad_token = tokenizer.eos_token - tokenizer.add_special_tokens(tokenizer_config.special_tokens) + # SpecialTokens : latest in 4.25, 4.26 + tokenizer.add_special_tokens( + { + "pad_token": tokenizer_config.special_tokens.pad_token, + "eos_token": tokenizer_config.special_tokens.eos_token, + "sep_token": tokenizer_config.special_tokens.sep_token, + } + ) additional_special_tokens = ( [] @@ -231,8 +238,8 @@ def get_dataset(conf, tokenizer): train = ConcatDataset(train_datasets) collate_fn = DialogueDataCollator(tokenizer, max_length=conf.max_length) - - return train, evals, collate_fn + train_collate_fn = TrainDialogueDataCollator(tokenizer, max_length=conf.max_length) + return train, evals, collate_fn, train_collate_fn def get_loss(loss, poly_eps): diff --git a/website/next-i18next.config.js b/website/next-i18next.config.js index 7eb7649b..aa1a4809 100644 --- a/website/next-i18next.config.js +++ b/website/next-i18next.config.js @@ -12,6 +12,7 @@ module.exports = { "eu", "fa", "fr", + "gl", "hu", "it", "ja", diff --git a/website/package-lock.json b/website/package-lock.json index 9b369be4..18b1fc19 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -85,6 +85,7 @@ "msw-storybook-addon": "^1.7.0", "prettier": "2.8.1", "prisma": "^4.7.1", + "ts-essentials": "^9.3.0", "ts-node": "^10.9.1", "typescript": "^4.9.4" } @@ -36509,6 +36510,15 @@ "node": ">=6.10" } }, + "node_modules/ts-essentials": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-9.3.0.tgz", + "integrity": "sha512-XeiCboEyBG8UqXZtXl59bWEi4ZgOqRsogFDI6WDGIF1LmzbYiAkIwjkXN6zZWWl4re/lsOqMlYfe8KA0XiiEPw==", + "dev": true, + "peerDependencies": { + "typescript": ">=4.1.0" + } + }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -66035,6 +66045,13 @@ "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==" }, + "ts-essentials": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-9.3.0.tgz", + "integrity": "sha512-XeiCboEyBG8UqXZtXl59bWEi4ZgOqRsogFDI6WDGIF1LmzbYiAkIwjkXN6zZWWl4re/lsOqMlYfe8KA0XiiEPw==", + "dev": true, + "requires": {} + }, "ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", diff --git a/website/package.json b/website/package.json index bb09c986..5e90432a 100644 --- a/website/package.json +++ b/website/package.json @@ -103,6 +103,7 @@ "msw-storybook-addon": "^1.7.0", "prettier": "2.8.1", "prisma": "^4.7.1", + "ts-essentials": "^9.3.0", "ts-node": "^10.9.1", "typescript": "^4.9.4" }, diff --git a/website/public/locales/ca/labelling.json b/website/public/locales/ca/labelling.json index f5fe2455..005e1604 100644 --- a/website/public/locales/ca/labelling.json +++ b/website/public/locales/ca/labelling.json @@ -1,24 +1,24 @@ { "fails_task.question": "És una mala resposta, segons la tasca demanada?", "hate_speech": "Incitació a l'odi", - "hate_speech.explanation": "El contingut és ofensiu o amenaçador i expressa un prejudici contra una característica protegida. El prejudici fa referència a les opinions preconcebudes que no es basen en la raó. Les característiques protegides inclouen gènere, ètnia, religió, orientació sexual i característiques semblants.", - "label_highlighted_flag_instruction": "Selecciona qualsevol que sigui adequat per al missatge ressaltat:", + "hate_speech.explanation": "El contingut és ofensiu o amenaçador i expressa un prejudici contra una característica protegida. Prejudici fa referència a les opinions preconcebudes que no es basen en la raó. Característiques protegides inclouen gènere, ètnia, religió, orientació sexual i característiques semblants.", + "label_highlighted_flag_instruction": "Selecciona'n qualsevol que sigui adequada per al missatge ressaltat:", "label_highlighted_likert_instruction": "Qualifica el missatge ressaltat:", - "label_highlighted_yes_no_instruction": "Contesta la/les següent/s pregunta/es sobre el missatge ressaltat:", - "label_message_flag_instruction": "Selecciona qualsevol que sigui adequada per al missatge:", + "label_highlighted_yes_no_instruction": "Contesta les preguntes següents sobre el missatge ressaltat:", + "label_message_flag_instruction": "Selecciona'n qualsevol que sigui adequada per al missatge:", "label_message_likert_instruction": "Qualifica el missatge:", - "label_message_yes_no_instruction": "Contesta la/les següent/s pregunta/es sobre el missatge:", - "lang_mismatch": "Idioma incorrecte", - "lang_mismatch.explanation": "No està escrit en l'idioma seleccionat actualment.", + "label_message_yes_no_instruction": "Contesta les preguntes següents sobre el missatge:", + "lang_mismatch": "No és {{language}}", + "lang_mismatch.explanation": "No està escrit en {{language}}.", "moral_judgement": "Judici moral", "moral_judgement.explanation": "Expressa un judici moral.", "not_appropriate": "No apropiada", "not_appropriate.explanation": "No apropiada per a un assistent de client.", - "pii": "Conté informació d'identificació personal (PII)", - "pii.explanation": "Conté informació personal com detalls de contacte personal, números d'identificació o detalls bancaris", + "pii": "Conté IPI", + "pii.explanation": "Conté Informació Personal Identificable, com detalls de contacte personal, números d'identificació personal o detalls bancaris", "political_content": "Contingut polític", "political_content.explanation": "Expressa una opinió política.", "sexual_content": "Contingut sexual", "sexual_content.explanation": "Conté contingut sexual.", - "spam.question": "És un missatge spam?" + "spam.question": "És un missatge brossa?" } diff --git a/website/public/locales/ca/leaderboard.json b/website/public/locales/ca/leaderboard.json index 0f3b01ad..21dca080 100644 --- a/website/public/locales/ca/leaderboard.json +++ b/website/public/locales/ca/leaderboard.json @@ -11,8 +11,8 @@ "rank": "Posició", "reply": "Respostes", "score": "Puntuació", - "top_5_contributors_today": "Top 5 contribuïdors avui", + "top_5_contributors_today": "Top 5 contribuïdors d'avui", "user": "Usuari", - "view_all": "Veure tots", + "view_all": "Mostra'ls tots", "weekly": "Setmanal" } diff --git a/website/public/locales/ca/message.json b/website/public/locales/ca/message.json index a6d35b16..86519dbf 100644 --- a/website/public/locales/ca/message.json +++ b/website/public/locales/ca/message.json @@ -1,20 +1,20 @@ { - "copy_message_id": "Copiar ID del missatge", - "label_action": "Etiquetar", + "copy_message_id": "Copia l'ID del missatge", + "label_action": "Etiqueta", "label_title": "Etiqueta", "message": "Missatge", - "message_deleted": "Missatge esborrat", - "open_new_tab_action": "Obrir en una pestanya nova", + "message_deleted": "S'ha suprimit el missatge", + "open_new_tab_action": "Obre en una pestanya nova", "parent": "Pare", "reactions": "Reaccions", "recent_messages": "Missatges recents", - "report_action": "Reportar", - "report_placeholder": "Per què cal revisar aquest missatge?", + "report_action": "Informa", + "report_placeholder": "Per què cal informar sobre aquest missatge?", "report_title": "Informe", - "send_report": "Enviar", - "stop_tree": "Aturar arbre", - "submit_labels": "Enviar", - "tree_stopped": "Arbre aturat {{id}}", - "view_user": "Veure usuari", + "send_report": "Envia", + "stop_tree": "Atura l'arbre", + "submit_labels": "Envia", + "tree_stopped": "S'ha aturat l'arbre {{id}}", + "view_user": "Mostra l'usuari", "your_recent_messages": "Els teus missatges recents" } diff --git a/website/public/locales/ca/tasks.json b/website/public/locales/ca/tasks.json index fe89c74c..1c527947 100644 --- a/website/public/locales/ca/tasks.json +++ b/website/public/locales/ca/tasks.json @@ -1,82 +1,82 @@ { "available_task_count": "{{count}} tasques disponibles", "classify_assistant_reply": { - "label": "Classificar resposta de l'assistent", + "label": "Classifica una resposta de l'assistent", "desc": "Proporciona etiquetes per a una resposta de l'assistent.", - "overview": "Llegeix la conversa següent i contesta a continuació la pregunta sobre l'última resposta a la discussió." + "overview": "Llegeix la conversa següent i contesta la pregunta relacionada amb l'última resposta." }, "classify_initial_prompt": { - "label": "Classificar instruccions inicials", - "desc": "Proporciona etiquetes per a unes instruccions.", - "overview": "Llegeix la següent entrada i contesta a continuació la pregunta sobre aquesta." + "label": "Classifica instruccions inicials", + "desc": "Proporciona etiquetes per a una instrucció.", + "overview": "Llegeix la instrucció següent i contesta la pregunta relacionada." }, "classify_prompter_reply": { - "label": "Classificar la resposta de l'apuntador", - "desc": "Proporciona etiquetes per a una entrada.", - "overview": "Llegeix la conversa següent i contesta a continuació la pregunta sobre l'última resposta a la discussió." + "label": "Classifica la resposta de l'apuntador", + "desc": "Proporciona etiquetes per a una instrucció.", + "overview": "Llegeix la conversa següent i contesta la pregunta relacionada amb l'última resposta." }, "create_initial_prompt": { - "label": "Crear instruccions inicials", - "desc": "Escriviu instruccions inicials per ajudar que Open Assistant intenti contestar missatges variats.", - "overview": "Crea un missatge inicial per enviar-lo a l'assistent", + "label": "Crea instruccions inicials", + "desc": "Escriu instruccions inicials perquè Open Assistant provi de contestar missatges variats.", + "overview": "Crea un missatge per a inciar conversa amb l'assistent", "instruction": "Proporciona les instruccions inicials", - "response_placeholder": "Escriu les teves instruccions aquí..." + "response_placeholder": "Escriu les instruccions aquí..." }, "default": { "unchanged_title": "Sense canvis", - "unchanged_message": "Estàs segur que vols continuar?" + "unchanged_message": "Segur que vols continuar?" }, "label_assistant_reply": { - "label": "Etiquetar resposta de l'assistent", - "desc": "Proporciona etiquetes per a unes instruccions.", - "overview": "Donada la discussió següent, proporciona etiquetes per a la darrera entrada." + "label": "Etiqueta la resposta de l'assistent", + "desc": "Proporciona etiquetes per a una instrucció.", + "overview": "Donada la conversa següent, proporciona etiquetes per a l'última entrada." }, "label_initial_prompt": { - "label": "Etiquetar instruccions inicials", - "desc": "Proporciona etiquetes per a unes instruccions.", - "overview": "Proporciona etiquetes per a les instruccions següents" + "label": "Etiqueta instruccions inicials", + "desc": "Proporciona etiquetes per a una instrucció.", + "overview": "Proporciona etiquetes per a la instrucció següent" }, "label_prompter_reply": { - "label": "Etiquetar resposta de l'apuntador", - "desc": "Proporciona etiquetes per a unes instruccions.", - "overview": "Donada la discussió següent, proporciona etiquetes per a la darrera entrada." + "label": "Etiqueta la resposta de l'apuntador", + "desc": "Proporciona etiquetes per a una instrucció.", + "overview": "Donada la conversa següent, proporciona etiquetes per a l'última entrada." }, "random": { - "label": "Tindré sort", + "label": "Segur que tinc sort", "desc": "Ajuda'ns a millorar Open Assistant començant amb una tasca aleatòria." }, "rank_assistant_replies": { - "label": "Ordenar respostes de l'assistent", - "desc": "Puntua respostes donades per Open Assistant basant-te en la precisió i llegibilitat.", - "overview": "Donades les respostes següents de l'assistent, ordeneu-les de millor a pitjor, amb la primera sent la millor i l'última, la pitjor.", + "label": "Classifica les respostes de l'assistent", + "desc": "Puntua les respostes d'Open Assistant basant-te en la precisió i llegibilitat.", + "overview": "Donades les respostes següents de l'assistent, ordena-les de millor a pitjor, sent la primera la millor i l'última, la pitjor.", "unchanged_title": "Ordre sense canviar", - "unchanged_message": "No heu canviat l'ordre de les respostes. Segur que vols continuar?" + "unchanged_message": "No has canviat l'ordre de les respostes. Segur que vols continuar?" }, "rank_initial_prompts": { - "label": "Ordenar instruccions inicials", - "desc": "Puntua instruccions a Open Assistant basant-te en la precisió i llegibilitat.", - "overview": "Donades les següents instruccions inicials, ordeneu-les de millor a pitjor, amb la primera sent la millor i l'última, la pitjor.", + "label": "Classifica les instruccions inicials", + "desc": "Puntua les instruccions donades a Open Assistant basant-te en la precisió i llegibilitat.", + "overview": "Donades les instruccions inicials següents, ordena-les de millor a pitjor, sent la primera la millor i l'última, la pitjor.", "unchanged_title": "Ordre sense canviar", - "unchanged_message": "No heu canviat l'ordre de les entrades. Segur que vols continuar?" + "unchanged_message": "No has canviat l'ordre de les entrades. Segur que vols continuar?" }, "rank_user_replies": { - "label": "Ordenar respostes d'usuaris", - "desc": "Ajuda Open Assistant a millorar les seves respostes a converses amb altres usuaris.", - "overview": "Donades les respostes següents d'usuaris, ordeneu-les de millor a pitjor, amb la primera sent la millor i l'última, la pitjor.", + "label": "Classifica les respostes dels usuaris", + "desc": "Ajuda Open Assistant a millorar les seves respostes en converses amb altres usuaris.", + "overview": "Donades les respostes següents d'usuaris, ordena-les de millor a pitjor, sent la primera la millor i l'última, la pitjor.", "unchanged_title": "Ordre sense canviar", - "unchanged_message": "No heu canviat l'ordre de les respostes. Segur que vols continuar?" + "unchanged_message": "No has canviat l'ordre de les respostes. Segur que vols continuar?" }, "reply_as_assistant": { - "label": "Contestar com a assistent", - "desc": "Ajuda Open Assistant a millorar les seves respostes a converses amb altres usuaris.", + "label": "Contesta com a assistent", + "desc": "Ajuda Open Assistant a millorar les seves respostes en converses amb altres usuaris.", "overview": "Donada la conversa següent, proporciona una resposta adequada", - "response_placeholder": "Escriu la teva resposta aquí..." + "response_placeholder": "Escriu la resposta aquí..." }, "reply_as_user": { - "label": "Contestar com a usuari", - "desc": "Parlar amb Open Assistant i intentar millorar les respostes mentre interacciones amb ell.", + "label": "Contesta com a usuari", + "desc": "Parla amb Open Assistant i intenta millorar les respostes mentre interacciones amb ell.", "overview": "Donada la conversa següent, proporciona una resposta adequada", "instruction": "Proporciona la resposta de l'usuari", - "response_placeholder": "Escriu la teva resposta aquí..." + "response_placeholder": "Escriu la resposta aquí..." } } diff --git a/website/public/locales/ca/tos.json b/website/public/locales/ca/tos.json index 62327390..2abf2a14 100644 --- a/website/public/locales/ca/tos.json +++ b/website/public/locales/ca/tos.json @@ -1,6 +1,6 @@ { - "accept": "Acceptar", - "content": "Per continuar utilitzant Open Assistant, primer has d'acceptar les nostres Condicions del servei.", - "decline": "Rebutjar", + "accept": "Accepta", + "content": "Per a continuar utilitzant Open Assistant, primer has d'acceptar les Condicions del servei.", + "decline": "Rebutja", "title": "Condicions del servei d'Open Assistant" } diff --git a/website/public/locales/en/common.json b/website/public/locales/en/common.json index 08ae1ee4..4edd313a 100644 --- a/website/public/locales/en/common.json +++ b/website/public/locales/en/common.json @@ -20,13 +20,20 @@ "messages": "Messages", "more_information": "More Information", "no": "No", + "output": "Output", "parameters": "Parameters", "privacy_policy": "Privacy Policy", + "prompt": "Prompt", "report_a_bug": "Report a Bug", + "review": "Review", "sign_in": "Sign In", "sign_out": "Sign Out", + "skip": "Skip", "status": "Status", "status_dashboard": "Status Dashboard", + "send": "Send", + "submit": "Submit", + "submit_your_answer": "Submit your answer", "success": "Success", "terms_of_service": "Terms of Service", "title": "Open Assistant", diff --git a/website/public/locales/en/labelling.json b/website/public/locales/en/labelling.json index fbf8c781..7367ae50 100644 --- a/website/public/locales/en/labelling.json +++ b/website/public/locales/en/labelling.json @@ -1,7 +1,35 @@ { + "accurate": "Accurate", + "apolitical": "Apolitical", + "appropriate": "Appropriate", + "boring": "Boring", + "clean": "Clean", + "contains_pii": "Contains PII", + "contains_pii.one_desc": "Contains personally identifying information", + "creative": "Creative", + "creative.one_desc": "Expresses creativity in responding to the task", + "fails_task": "Fails Task", + "fails_task.one_desc": "Fails to follow the correct instruction / task", "fails_task.question": "Is it a bad reply, as an answer to the prompt task?", + "follows_instructions": "Follows Instructions", + "harmful": "Harmful", + "harmful.one_desc.line_1": "Content likely to cause excessive harm not justifiable in the context", + "harmful.one_desc.line_2": "Harm refers to physical or mental damage or injury to someone or something. Excessive refers to a reasonable threshold of harm in the context, for instance damaging skin is not excessive in the context of surgery.", + "harmless": "Harmless", "hate_speech": "Hate Speech", "hate_speech.explanation": "Content is abusive or threatening and expresses prejudice against a protected characteristic. Prejudice refers to preconceived views not based on reason. Protected characteristics include gender, ethnicity, religion, sexual orientation, and similar characteristics.", + "hateful": "Hateful", + "hateful.one_desc.line_1": "Content is abusive or threatening and expresses prejudice against a protected characteristic", + "hateful.one_desc.line_2": "Prejudice refers to preconceived views not based on reason. Protected characteristics include gender, ethnicity, religion, sexual orientation, and similar characteristics.", + "helpful": "Helpful", + "helpful.one_desc": "Completes the task to a high standard", + "high_quality": "High Quality", + "humorous": "Humorous", + "humorous.one_desc": "Contains humorous content including sarcasm", + "inappropriate": "Inappropriate", + "inappropriate.one_desc": "Inappropriate for customer assistant", + "judgemental": "Judgemental", + "judgemental.one_desc": "Expresses moral judgement", "label_highlighted_flag_instruction": "Select any that apply to the highlighted message:", "label_highlighted_likert_instruction": "Rate the highlighted message:", "label_highlighted_yes_no_instruction": "Answer the following question(s) about the highlighted message:", @@ -10,15 +38,42 @@ "label_message_yes_no_instruction": "Answer the following question(s) about the message:", "lang_mismatch": "Not {{language}}", "lang_mismatch.explanation": "Not written in {{language}}.", + "low_quality": "Low Quality", + "misleading": "Misleading", + "misleading.one_desc": "Contains text which is incorrect or misleading", "moral_judgement": "Judges Morality", "moral_judgement.explanation": "Expresses moral judgement.", + "non_judgemental": "Non-judgemental", + "non_sexual": "Non-sexual", + "not_spam": "Not spam", + "not_spam.explanation": "Suitable for training Open Assistant.", "not_appropriate": "Not Appropriate", "not_appropriate.explanation": "Inappropriate for a customer assistant.", + "ordinary": "Ordinary", "pii": "Contains PII", "pii.explanation": "Contains personally identifying information. Examples include personal contact details, license and other identity numbers and banking details.", + "polite": "Polite", + "political": "Political", "political_content": "Political", "political_content.explanation": "Expresses political views.", + "political.one_desc": "Expresses political views", + "rude": "Rude", + "rude.one_desc": "Contains rude, abusive, profane or insulting content", + "safe": "Safe", + "serious": "Serious", + "spam": "Spam", + "spam.question": "Is the message spam?", + "spam.one_desc.line_1": "Seems to be intentionally low-quality or irrelevant", + "spam.one_desc.line_2": "We consider the following unwanted content as spam: trolling, intentional undermining of our purpose, illegal material, material that violates our code of conduct, and other things that are inappropriate for our dataset. We collect these under the common heading of \"spam\".", + "spam.one_desc.line_3": "This is not an assessment of whether this message is the best possible answer. Especially for prompts or user-replies, we very much want to retain all kinds of responses in the dataset, so that the assistant can learn to reply appropriately.", + "spam.one_desc.line_4": "Please mark this text as spam only if it is clearly unsuited to be part of our dataset, as outlined above, and try not to make any subjective value-judgments beyond that.", + "sexual": "Sexual", "sexual_content": "Sexual Content", "sexual_content.explanation": "Contains sexual content.", - "spam.question": "Is the message spam?" + "sexual.one_desc": "Contains sexual content", + "threatening": "Threatening", + "threatening.one_desc": "Contains a threat against a person or persons", + "unhelpful": "Unhelpful", + "violent": "Violent", + "violent.one_desc": "Encourages or fails to discourage violence/abuse/terrorism/self-harm" } diff --git a/website/public/locales/en/leaderboard.json b/website/public/locales/en/leaderboard.json index 2339a05d..68805e04 100644 --- a/website/public/locales/en/leaderboard.json +++ b/website/public/locales/en/leaderboard.json @@ -12,6 +12,8 @@ "month": "Month", "monthly": "Monthly", "next": "Next", + "no_email": "(No email)", + "no_username": "(No username)", "overall": "Overall", "previous": "Previous", "prompt": "Prompts", @@ -25,6 +27,7 @@ "top_5_contributors_today": "Top 5 Contributors Today", "total": "Total", "user": "User", + "username": "Username", "view_all": "View all", "week": "Week", "weekly": "Weekly", diff --git a/website/public/locales/en/tasks.json b/website/public/locales/en/tasks.json index f4ac9ef5..6ae9ed36 100644 --- a/website/public/locales/en/tasks.json +++ b/website/public/locales/en/tasks.json @@ -1,4 +1,6 @@ { + "any_feedback_on_this_task": "Any feedback on this task?", + "available_task_count": "{{count}} tasks available", "default": { "unchanged_title": "No changes", "unchanged_message": "Are you sure you would like to continue?" @@ -78,7 +80,6 @@ "desc": "Provide labels for a prompt.", "overview": "Read the following conversation and then answer the question about the last reply in the discussion." }, - "available_task_count": "{{count}} tasks available", - "writing_wrong_langauge_a_b": "You appear to be writing in {{detected_lang}} but this will be submitted as {{submit_lang}}.", - "submitted_as": "This will be submitted as {{submit_lang}}" + "submitted_as": "This will be submitted as {{submit_lang}}", + "writing_wrong_langauge_a_b": "You appear to be writing in {{detected_lang}} but this will be submitted as {{submit_lang}}." } diff --git a/website/public/locales/es/common.json b/website/public/locales/es/common.json index 4a663534..cdcd9158 100644 --- a/website/public/locales/es/common.json +++ b/website/public/locales/es/common.json @@ -20,13 +20,20 @@ "messages": "Mensajes", "more_information": "Más información", "no": "No", + "output": "Salida", "parameters": "Parámetros", "privacy_policy": "Política de privacidad", + "prompt": "Indicación", "report_a_bug": "Informar de un error", + "review": "Revisar", "sign_in": "Iniciar sesión", "sign_out": "Cerrar sesión", + "skip": "Saltar", "status": "Estado", "status_dashboard": "Tablón de estado", + "send": "Enviar", + "submit": "Enviar", + "submit_your_answer": "Enviar tu respuesta", "success": "Éxito", "terms_of_service": "Términos de servicio", "title": "Open Assistant", diff --git a/website/public/locales/es/index.json b/website/public/locales/es/index.json index 5e236c29..e5889250 100644 --- a/website/public/locales/es/index.json +++ b/website/public/locales/es/index.json @@ -1,6 +1,6 @@ { "blurb": "Creemos que podemos crear una revolución.", - "blurb1": "De la misma manera que Stable Diffusion ayudó al mundo a crear arte e imágenes de maneras nuevas, queremos mejorar el mundo proporcionando una IA conversacional asombrosa", + "blurb1": "De la misma forma que Stable Diffusion ayudó al mundo a crear arte e imágenes de nuevas maneras, queremos mejorar el mundo proporcionando una IA conversacional asombrosa.", "description": "IA conversacional para todos. Un proyecto de código abierto para crear un GPT LLM preparado para chatear administrado por LAION y colaboradores de todo el mundo.", "faq_items": { "q0": "¿Cómo de avanzado está el proyecto?", @@ -16,7 +16,7 @@ "q5": "¿Qué hardware será necesario para ejecutar los modelos?", "a5": "Habrá versiones que se podrán ejecutar en hardware de consumo." }, - "faq_title": "Preguntas frequentes", + "faq_title": "Preguntas frecuentes", "join_us_description": "Todos los proyectos de código abierto comienzan con personas como tú. El código abierto es la creencia de que si colaboramos juntos, podemos regalar nuestro conocimiento y tecnología al mundo en beneficio de la humanidad. ¿Te apuntas? Encuéntranos aquí:", "join_us_title": "Únete a nosotros", "subtitle": "IA conversacional para todos." diff --git a/website/public/locales/es/labelling.json b/website/public/locales/es/labelling.json index 522b827e..7749e8e6 100644 --- a/website/public/locales/es/labelling.json +++ b/website/public/locales/es/labelling.json @@ -1,24 +1,79 @@ { + "accurate": "Preciso", + "apolitical": "Apolítico", + "appropriate": "Apropriado", + "boring": "Aburrido", + "clean": "Limpio", + "contains_pii": "Contiene PII", + "contains_pii.one_desc": "Contiene información de identificación personal (PII)", + "creative": "Creativo", + "creative.one_desc": "Expresa creatividad en la respuesta a la tarea", + "fails_task": "Falla en la tarea", + "fails_task.one_desc": "Falla en seguir las instrucciones/tareas correctas", "fails_task.question": "¿Es una mala respuesta, según la tarea pedida?", + "follows_instructions": "Sigue las instrucciones", + "harmful": "Dañino", + "harmful.one_desc.line_1": "Contenido que probablemente cause daño excesivo no justificable por el contexto", + "harmful.one_desc.line_2": "Daño se refiere a hacer daño o causar heridas a alguien o algo. Excesivo se refiere a un nivel de daño razonable en el contexto, por ejemplo, dañar la piel no es excesivo en el contexto de una operación.", + "harmless": "Inofensivo", "hate_speech": "Incitación al odio", "hate_speech.explanation": "El contenido es ofensivo o amenazante y expresa un prejuicio contra una característica protegida. El prejuicio se refiere a las opiniones preconcebidas que no se basan en la razón. Las características protegidas incluyen género, etnia, religión, orientación sexual y características similares.", + "hateful": "Odiosa", + "hateful.one_desc.line_1": "El contenido es abusivo o amenazante y expresa prejuicio contra una característica protegida", + "hateful.one_desc.line_2": "El prejuicio se refiere a puntos de vista preconcebidos que no se basan en la razón. Las características protegidas incluyen género, etnia, religión, orientación sexual y características similares.", + "helpful": "Útil", + "helpful.one_desc": "Completa la tarea con un alto nivel", + "high_quality": "Alta calidad", + "humorous": "Humorístico", + "humorous.one_desc": "Contiene contenido humorístico, incluyendo sarcasmo.", + "inappropriate": "Inapropiado", + "inappropriate.one_desc": "Inapropiado para asistente de cliente", + "judgemental": "Moralista", + "judgemental.one_desc": "Expresa un juicio moral", "label_highlighted_flag_instruction": "Selecciona cualquiera que sea adecuada para el mensaje resaltado:", "label_highlighted_likert_instruction": "Califica el mensaje resaltado:", "label_highlighted_yes_no_instruction": "Contesta la(s) siguiente(s) pregunta(s) sobre el mensaje resaltado:", "label_message_flag_instruction": "Selecciona cualquiera que sea adecuada para el mensaje:", "label_message_likert_instruction": "Califica el mensaje:", "label_message_yes_no_instruction": "Contesta la(s) siguiente(s) pregunta(s) sobre el mensaje:", - "lang_mismatch": "Idioma incorrecto", - "lang_mismatch.explanation": "No está escrito en el idioma seleccionado actualmente.", + "lang_mismatch": "No está en {{language}}", + "lang_mismatch.explanation": "No está escrito en {{language}}.", + "low_quality": "Baja calidad", + "misleading": "Engañoso", + "misleading.one_desc": "Contiene texto incorrecto o engañoso", "moral_judgement": "Juicio moral", "moral_judgement.explanation": "Expresa un juicio moral.", + "non_judgemental": "No crítico", + "non_sexual": "No es sexual", + "not_spam": "No es spam", + "not_spam.explanation": "Apto para entrenar Open Assistant.", "not_appropriate": "No apropiada", - "not_appropriate.explanation": "No apropiada para un asistente de cliente.", + "not_appropriate.explanation": "No apropiada para un asistente.", + "ordinary": "Corriente", "pii": "Contiene información de identificación personal (PII)", "pii.explanation": "Contiene información personal como detalles de contacto personal, números de identificación o detalles bancarios", + "polite": "Educado", + "political": "Político", "political_content": "Contenido político", "political_content.explanation": "Expresa una opinión política.", + "political.one_desc": "Expresa opiniones políticas", + "rude": "Maleducado", + "rude.one_desc": "Contiene contenido grosero, abusivo, soez o insultante.", + "safe": "Seguro", + "serious": "Serio", + "spam": "Spam", + "spam.question": "¿Es el mensaje spam?", + "spam.one_desc.line_1": "Parece ser intencionalmente de baja calidad o irrelevante", + "spam.one_desc.line_2": "Consideramos el siguiente contenido no deseado como spam: trolear, socavación intencionada de nuestro propósito, material ilegal, material que viola nuestro código de conducta y otras cosas que son inapropiadas para nuestro conjunto de datos. Recopilamos todo esto bajo el encabezado común de \"spam\".", + "spam.one_desc.line_3": "Esta no es una evaluación de si este mensaje es la mejor respuesta posible. Especialmente para las instrucciones o las respuestas de los usuarios, queremos conservar todo tipo de respuestas en el conjunto de datos, para que el asistente pueda aprender a responder adecuadamente.", + "spam.one_desc.line_4": "Marque este texto como spam solo si es claramente inadecuado para ser parte de nuestro conjunto de datos, como se describe anteriormente, y trate de no hacer ningún juicio de valor subjetivo más allá de eso.", + "sexual": "Sexual", "sexual_content": "Contenido sexual", "sexual_content.explanation": "Contiene contenido sexual.", - "spam.question": "¿Es el mensaje spam?" + "sexual.one_desc": "Contiene contenido sexual", + "threatening": "Amenazante", + "threatening.one_desc": "Contiene una amenaza contra una o varias personas", + "unhelpful": "De poca ayuda", + "violent": "Violento", + "violent.one_desc": "Fomenta o no desalienta la violencia, el abuso, el terrorismo o las autolesiones" } diff --git a/website/public/locales/es/leaderboard.json b/website/public/locales/es/leaderboard.json index bb76060f..4e9da50f 100644 --- a/website/public/locales/es/leaderboard.json +++ b/website/public/locales/es/leaderboard.json @@ -12,6 +12,8 @@ "month": "Mes", "monthly": "Mensual", "next": "Siguiente", + "no_email": "(Sin dirección de correo)", + "no_username": "(Sin nombre de usuario)", "overall": "Global", "previous": "Anterior", "prompt": "Indicaciones", @@ -25,6 +27,7 @@ "top_5_contributors_today": "5 mayores contribuidores hoy", "total": "Total", "user": "Usuario", + "username": "Nombre de usuario", "view_all": "Ver todos", "week": "Semana", "weekly": "Semanal", diff --git a/website/public/locales/es/tasks.json b/website/public/locales/es/tasks.json index da761255..df8f7394 100644 --- a/website/public/locales/es/tasks.json +++ b/website/public/locales/es/tasks.json @@ -1,4 +1,5 @@ { + "any_feedback_on_this_task": "¿Alguna realimentación sobre esta tarea?", "available_task_count": "{{count}} tareas disponibles", "classify_assistant_reply": { "label": "Clasificar respuesta del asistente", @@ -79,6 +80,6 @@ "instruction": "Proporciona la respuesta del usuario", "response_placeholder": "Escribe tu respuesta aquí..." }, - "writing_wrong_langauge_a_b": "Parece que estás escribiendo en {{detected_lang}} pero esto se enviará como {{submit_lang}}.", - "submitted_as": "Esto será enviado como {{submit_lang}}" + "submitted_as": "Esto será enviado como {{submit_lang}}", + "writing_wrong_langauge_a_b": "Parece que estás escribiendo en {{detected_lang}} pero esto se enviará como {{submit_lang}}." } diff --git a/website/public/locales/eu/tasks.json b/website/public/locales/eu/tasks.json index aa5ea58d..7f5b4178 100644 --- a/website/public/locales/eu/tasks.json +++ b/website/public/locales/eu/tasks.json @@ -2,21 +2,21 @@ "available_task_count": "{{count}} zeregin eskuragarri", "classify_assistant_reply": { "desc": "Jarri etiketak instrukzio bati.", - "label": "Sailifikatu Laguntzailea eginbidearen erantzuna", + "label": "Sailkatu asistentearen erantzuna", "overview": "Irakurri hurrengo elkarrizketa eta erantzun elkarrizketako azken erantzunari buruzko galdera." }, "classify_initial_prompt": { "desc": "Jarri etiketak instrukzio bati.", - "label": "Salifikatu hasierako instrukzioa", + "label": "Sailkatu hasierako instrukzioa", "overview": "Irakurri hurrengo instrukzioa eta erantzun horri buruzko galdera." }, "classify_prompter_reply": { "desc": "Jarri etiketak instrukzio bati.", - "label": "Sailifikatu galdetzailearen erantzuna", + "label": "Sailkatu erabiltzailearen erantzuna", "overview": "Irakurri hurrengo elkarrizketa eta erantzun elkarrizketako azken erantzunari buruzko galdera." }, "create_initial_prompt": { - "desc": "Idatzi hasierako instrukzioak Open Assistant-i era askotako mezuak erantzuten saia dadin. (sartu loterian)", + "desc": "Idatzi hasierako instrukzioak Open Assistant era askotako mezuak erantzuten saia dadin.", "instruction": "Eman hasierako instrukzioak", "label": "Sortu hasierako instrukzioak", "overview": "Sortu hasierako mezu bat asistenteari bidaltzeko", @@ -79,6 +79,6 @@ "overview": "Ondoko elkarrizketa ikusita, eman erantzun egokia", "response_placeholder": "Idatzi zure erantzuna hemen..." }, - "submitted_as": "Hau {{submit_lang}} hizkuntzan bidaliko da ", + "submitted_as": "Hau {{submit_lang}} hizkuntzan bidaliko da", "writing_wrong_langauge_a_b": "Ematen du {{detected_lang}} hizkuntzan baina hau {{submit_lang}} hizkuntzan bidaliko da." } diff --git a/website/public/locales/gl/common.json b/website/public/locales/gl/common.json new file mode 100644 index 00000000..747660ce --- /dev/null +++ b/website/public/locales/gl/common.json @@ -0,0 +1,38 @@ +{ + "about": "Acerca", + "account_settings": "Conta", + "admin_dashboard": "Panel de administración", + "connect": "Conectar", + "conversational": "IA conversacional para todos", + "copied": "Copiado", + "dark_mode": "Modo escuro", + "dashboard_home": "Panel principal", + "dashboard": "Panel", + "delete": "Eliminar", + "discord": "Discord", + "docs": "Documentación", + "github": "GitHub", + "leaderboard": "Táboa de líderes", + "legal": "Legal", + "light_mode": "Modo claro", + "loading": "Cargando...", + "messages_dashboard": "Panel de mensaxes", + "messages": "Mensaxes", + "more_information": "Máis información", + "no": "Non", + "parameters": "Parámetros", + "privacy_policy": "Política de privacidade", + "report_a_bug": "Informar dun erro", + "sign_in": "Iniciar sesión", + "sign_out": "Pechar sesión", + "status": "Estado", + "status_dashboard": "Panel de estado", + "success": "Éxito", + "terms_of_service": "Termos de servizo", + "title": "Open Assistant", + "trollboard": "Trollboard", + "user_leaderboard": "Táboa de usuarios", + "users_dashboard": "Panel de usuario", + "users": "Usuarios", + "yes": "Si" +} diff --git a/website/public/locales/gl/dashboard.json b/website/public/locales/gl/dashboard.json new file mode 100644 index 00000000..96a63f7e --- /dev/null +++ b/website/public/locales/gl/dashboard.json @@ -0,0 +1,8 @@ +{ + "grab_a_task": "Colle unha tarefa!", + "create": "Crear", + "evaluate": "Avaliar", + "label": "Etiqueta", + "dashboard": "Panel", + "go": "Ir" +} diff --git a/website/public/locales/gl/index.json b/website/public/locales/gl/index.json new file mode 100644 index 00000000..d013cedd --- /dev/null +++ b/website/public/locales/gl/index.json @@ -0,0 +1,23 @@ +{ + "blurb": "Cremos que podemos crear unha revolución.", + "blurb1": "Do mesmo xeito que Stable Diffusion axudou ao mundo a facer arte e imaxes de novas maneiras, queremos mellorar o mundo proporcionando unha incríbel IA conversacional.", + "description": "AI conversacional para todos. Un proxecto de código aberto para crear un chat habilitado con GPT LLM dirixido por LAION e colaboradores de todo o mundo.", + "faq_items": { + "q0": "Como de avanzado está o proxecto?", + "a0": "Estamos nas primeiras etapas de desenvolvemento, traballando dende a investigación establecida na aplicación de RLHF (aprendizaxe por reforzo con retroalimentación humana) ata grandes modelos de linguaxe.", + "q1": "Quen está detrás de Open Assistant?", + "a1": "Open Assistant é un proxecto organizado por LAION e individuos de todo o mundo interesados en achegar esta tecnoloxía á xente.", + "q2": "Que licencia emprega Open Assistant?", + "a2": "O código e os modelos están licenciados baixo a licencia Apache 2.0.", + "q3": "Serán publicados os datos de adestramento?", + "a3": "Si, baixo a licencia CC BY 4.0.", + "q4": "Será Open Assistant libre?", + "a4": "Si, Open Assistant será libre de usar e modificar.", + "q5": "Que hardware será necesario para executar os modelos?", + "a5": "Haberá versións que se poderán executar en hardware de consumo." + }, + "faq_title": "Preguntas frecuentes", + "join_us_description": "Tódolos proxectos de código aberto comezan con xente coma ti. O código aberto é a crenza de que se colaboramos podemos agasallar o noso coñecemento e tecnoloxía ao mundo en beneficio da humanidade. Estás dentro? Atópanos aquí:", + "join_us_title": "Únete a nós", + "subtitle": "AI conversacional para todo o mundo." +} diff --git a/website/public/locales/gl/labelling.json b/website/public/locales/gl/labelling.json new file mode 100644 index 00000000..658d8804 --- /dev/null +++ b/website/public/locales/gl/labelling.json @@ -0,0 +1,24 @@ +{ + "fails_task.question": "É unha mala reposta, segundo a tarefa pedida?", + "hate_speech": "Incitación ao odio", + "hate_speech.explanation": "Contido abusivo ou ameazante que expresa prexuicios contra unha característica protexida. O prexuízo refírese a opinións preconcebidas que non se basean na razón. As características protexidas inclúen o xénero, a etnia, a relixión, a orientación sexual e similares.", + "label_highlighted_flag_instruction": "Elixe calquera que sexa adoitada para a mensaxe destacada:", + "label_highlighted_likert_instruction": "Valora a mensaxe destacada:", + "label_highlighted_yes_no_instruction": "Responde á(s) seguinte(s) pregunta(s) sobre a mensaxe destacada:", + "label_message_flag_instruction": "Elixe calquera que sexa adoitada para a mensaxe:", + "label_message_likert_instruction": "Califica a mensaxe:", + "label_message_yes_no_instruction": "Responde á(s) seguinte(s) pregunta(s) sobre a mensaxe:", + "lang_mismatch": "Non é {{language}}", + "lang_mismatch.explanation": "Non está escrito en {{language}}.", + "moral_judgement": "Xuízo moral", + "moral_judgement.explanation": "Expresa xuízo moral.", + "not_appropriate": "Non apropiado", + "not_appropriate.explanation": "Non apropiado para un asistente.", + "pii": "Contén información de identificación persoal (PII)", + "pii.explanation": "Contén información de identificación persoal. Algúns exemplos son: detalles de contacto persoais, números de licenza e de identidade e detalles bancarios.", + "political_content": "Contido político", + "political_content.explanation": "Expresa opinións políticas.", + "sexual_content": "Contido sexual", + "sexual_content.explanation": "Contén contido sexual.", + "spam.question": "É spam?" +} diff --git a/website/public/locales/gl/leaderboard.json b/website/public/locales/gl/leaderboard.json new file mode 100644 index 00000000..e2f997d9 --- /dev/null +++ b/website/public/locales/gl/leaderboard.json @@ -0,0 +1,33 @@ +{ + "accepted": "↪ Aceptadas", + "accepted_prompts": "Indicacións aceptadas", + "daily": "Diario", + "day": "Día", + "good_rankings": "Boas calificacións", + "label": "Etiquetas", + "labels_full": "Etiquetas (completas)", + "labels_simple": "Etiquetas (sinxelas)", + "last_updated_at": "Última actualización: {{val, datetime}}", + "leaderboard": "Táboa de líderes", + "month": "Mes", + "monthly": "Mensual", + "next": "Seguinte", + "overall": "Global", + "previous": "Anterior", + "prompt": "Indicacións", + "rank": "Posición", + "rankings": "Clasificacións", + "replies_assistant": "Resposta como asistente", + "replies_prompter": "Resposta como apuntador", + "reply": "Respostas", + "reply_ranked_1": "Resposta calificada como 1ª", + "score": "Puntuación", + "top_5_contributors_today": "Os 5 principais colaboradores de hoxe", + "total": "Total", + "user": "Usuario", + "view_all": "Ver todo", + "week": "Semana", + "weekly": "Semanal", + "your_account": "A túa conta", + "your_stats": "As túas estatísticas" +} diff --git a/website/public/locales/gl/message.json b/website/public/locales/gl/message.json new file mode 100644 index 00000000..28e5a43a --- /dev/null +++ b/website/public/locales/gl/message.json @@ -0,0 +1,21 @@ +{ + "copy_message_id": "Copiar ID da mensaxe", + "copy_message_link": "Copiar ligazón da mensaxe", + "label_action": "Etiquetar", + "label_title": "Etiqueta", + "message_deleted": "Mensaxe eliminada", + "message": "Mensaxe", + "open_new_tab_action": "Abrir nunha nova lapela", + "parent": "Pai", + "reactions": "Reaccións", + "recent_messages": "Mensaxes recentes en {{language}}", + "report_action": "Informar", + "report_placeholder": "Porque se debería informar desta mensaxe?", + "report_title": "Informe", + "send_report": "Enviar informe", + "stop_tree": "Parar árbore", + "submit_labels": "Enviar", + "tree_stopped": "Árbore parado {{id}}", + "view_user": "Ver usuario", + "your_recent_messages": "As túas mensaxes recentes" +} diff --git a/website/public/locales/gl/tasks.json b/website/public/locales/gl/tasks.json new file mode 100644 index 00000000..de1bffd7 --- /dev/null +++ b/website/public/locales/gl/tasks.json @@ -0,0 +1,84 @@ +{ + "default": { + "unchanged_title": "Sen cambios", + "unchanged_message": "Estás seguro de que desexas continuar?" + }, + "random": { + "label": "Vou ter sorte", + "desc": "Axúdanos a mellorar Open Assistant comezando unha tarefa aleatoria." + }, + "create_initial_prompt": { + "label": "Crea Indicacións Iniciais", + "desc": "Escribe as indicacións iniciais para axudar a Open Assistant a responder a diversas mensaxes.", + "overview": "Crea unha mensaxe inicial para enviar ao asistente", + "instruction": "Proporciona as indicacións iniciais", + "response_placeholder": "Escribe a túa indicación aquí..." + }, + "reply_as_user": { + "label": "Responder como usuario", + "desc": "Fala con Open Assistant e axuda a mellorar as súas respostas mentres interactúas con él.", + "overview": "Dada a seguinte conversa, proporciona unha resposta axeitada", + "instruction": "Proporciona a resposta de usuario", + "response_placeholder": "Escribe a túa resposta aquí..." + }, + "reply_as_assistant": { + "label": "Responder como asistente", + "desc": "Axuda a Open Assistant a mellorar as súas respostas a conversas con outros usuarios.", + "overview": "Dada a seguinte conversa, proporciona unha resposta axeitada", + "response_placeholder": "Escribe a túa resposta aquí..." + }, + "rank_user_replies": { + "label": "Califica as respostas dos usuarios", + "desc": "Axuda a Open Assistant a mellorar as súas respostas a conversas con outros usuarios.", + "overview": "Dadas as seguintes respostas de usuarios, ordéaas da mellor á peor, sendo a mellor a primeira e a peor a última.", + "unchanged_title": "Orde sen cambios", + "unchanged_message": "Non cambiaches a orde das respostas. Estás seguro de que desexas continuar?" + }, + "rank_assistant_replies": { + "label": "Califica as respostas do asistente", + "desc": "Califica indicacións dadas por Open Assistant en función da súa precisión e lexibilidade.", + "overview": "Dadas as seguintes respostas do asistente, ordéaas da mellor á peor, sendo a mellor a primeira e a peor a última.", + "unchanged_title": "Orde sen cambios", + "unchanged_message": "Non cambiaches a orde das respostas. Estás seguro de que desexas continuar?" + }, + "rank_initial_prompts": { + "label": "Califica as indicacións iniciais", + "desc": "Califica indicacións dadas por Open Assistant en función da súa precisión e lexibilidade.", + "overview": "Dadas as seguintes indicacións iniciais, ordéaas da mellor á peor, sendo a mellor a primeira e a peor a última.", + "unchanged_title": "Orde sen cambios", + "unchanged_message": "Non cambiaches a orde das respostas. Estás seguro de que desexas continuar?" + }, + "label_initial_prompt": { + "label": "Etiqueta de Indicacións Iniciais", + "desc": "Proporciona etiquetas para unha indicación.", + "overview": "Proporciona etiquetas para a seguinte indicación" + }, + "label_prompter_reply": { + "label": "Etiqueta de Resposta do Apuntador", + "desc": "Proporciona etiquetas para unha indicación.", + "overview": "Dada a seguinte conversa, proporciona etiquetas para a indicación final." + }, + "label_assistant_reply": { + "label": "Etiqueta de Resposta do Asistente", + "desc": "Proporciona etiquetas para unha indicación.", + "overview": "Dada a seguinte conversa, proporciona etiquetas para a indicación final." + }, + "classify_initial_prompt": { + "label": "Clasifica as Indicación Inicial", + "desc": "Proporciona etiquetas para unha indicación.", + "overview": "Le a seguinte indicación e responde á pregunta acerca dela." + }, + "classify_prompter_reply": { + "label": "Clasifica as Repostas do Apuntador", + "desc": "Proporciona etiquetas para unha indicación.", + "overview": "Le a seguinte conversa e responde á pregunta do final." + }, + "classify_assistant_reply": { + "label": "Clasifica as Repostas do Asistente", + "desc": "Proporciona etiquetas para unha indicación.", + "overview": "Le a seguinte conversa e responde á pregunta do final." + }, + "available_task_count": "{{count}} tarefas dispoñibles", + "writing_wrong_langauge_a_b": "Parece que estás a escribir en {{detected_lang}} pero esto vai ser enviado en como {{submit_lang}}.", + "submitted_as": "Esto vai ser enviado como {{submit_lang}}" +} diff --git a/website/public/locales/gl/tos.json b/website/public/locales/gl/tos.json new file mode 100644 index 00000000..122971a5 --- /dev/null +++ b/website/public/locales/gl/tos.json @@ -0,0 +1,6 @@ +{ + "title": "Termos de Servicio para Open Assistant", + "content": "Para continuar usando Open Assistant, tes que aceptar os nosos Termos de Servicio primeiro.", + "accept": "Aceptar", + "decline": "Rexeitar" +} diff --git a/website/src/components/Buttons/Skip.tsx b/website/src/components/Buttons/Skip.tsx index bcd0eb79..f966cde7 100644 --- a/website/src/components/Buttons/Skip.tsx +++ b/website/src/components/Buttons/Skip.tsx @@ -11,6 +11,7 @@ import { Textarea, useDisclosure, } from "@chakra-ui/react"; +import { useTranslation } from "next-i18next"; import { useState } from "react"; interface SkipButtonProps extends ButtonProps { @@ -18,6 +19,7 @@ interface SkipButtonProps extends ButtonProps { } export const SkipButton = ({ onSkip, ...props }: SkipButtonProps) => { + const { t } = useTranslation(["common", "tasks"]); const { isOpen, onOpen: showModal, onClose: closeModal } = useDisclosure(); const [value, setValue] = useState(""); @@ -30,25 +32,25 @@ export const SkipButton = ({ onSkip, ...props }: SkipButtonProps) => { return ( <> - Skip + {t("skip")}