আপনার নিজস্ব স্ক্রিপ্ট নিয়ে আসা Hugging Face Amazon SageMaker কন্টেইনারগুলি ব্যবহার করে একটি সারাংশের মডেল ফাইন-টিউন করুন এবং স্থাপন করুন

NLP ডোমেনে সাম্প্রতিক অনেক অগ্রগতি হয়েছে। প্রাক-প্রশিক্ষিত মডেল এবং সম্পূর্ণরূপে পরিচালিত এনএলপি পরিষেবাগুলি গণতান্ত্রিকভাবে এনএলপি অ্যাক্সেস এবং গ্রহণ করেছে। অ্যামাজন সমঝোতা এটি একটি সম্পূর্ণরূপে পরিচালিত পরিষেবা যা এনএলপি কার্য সম্পাদন করতে পারে যেমন কাস্টম সত্তা স্বীকৃতি, বিষয় মডেলিং, অনুভূতি বিশ্লেষণ এবং আরও অনেক কিছুর জন্য কোনও পূর্বের এমএল অভিজ্ঞতার প্রয়োজন ছাড়াই ডেটা থেকে অন্তর্দৃষ্টি বের করতে৷

গত বছর এডব্লিউএস ঘোষণা করেছে একটি অংশীদারিত্ব সঙ্গে আলিঙ্গন মুখ ন্যাচারাল ল্যাঙ্গুয়েজ প্রসেসিং (NLP) মডেলগুলিকে দ্রুত উৎপাদনে আনতে সাহায্য করার জন্য। হাগিং ফেস হল একটি ওপেন সোর্স এআই সম্প্রদায়, যা NLP-এর উপর দৃষ্টি নিবদ্ধ করে৷ তাদের পাইথন-ভিত্তিক লাইব্রেরি (ট্রান্সফরমার) BERT, RoBERta, এবং GPT এর মতো জনপ্রিয় অত্যাধুনিক ট্রান্সফরমার আর্কিটেকচারগুলিকে সহজেই ব্যবহার করার জন্য সরঞ্জাম সরবরাহ করে৷ আপনি এই মডেলগুলিকে বিভিন্ন এনএলপি কাজগুলিতে প্রয়োগ করতে পারেন, যেমন পাঠ্য শ্রেণিবিন্যাস, তথ্য নিষ্কাশন এবং প্রশ্নের উত্তর দেওয়া। অন্যদের.

আমাজন সেজমেকার এটি একটি সম্পূর্ণরূপে পরিচালিত পরিষেবা যা ডেভেলপার এবং ডেটা বিজ্ঞানীদের দ্রুত মেশিন লার্নিং (ML) মডেলগুলি তৈরি, প্রশিক্ষণ এবং স্থাপন করার ক্ষমতা প্রদান করে৷ SageMaker ML প্রক্রিয়ার প্রতিটি ধাপ থেকে ভারী উত্তোলন সরিয়ে দেয়, এটি উচ্চ-মানের মডেলগুলি বিকাশ করা সহজ করে তোলে। SageMaker Python SDK ওপেন-সোর্স API এবং কন্টেইনার সরবরাহ করে SageMaker-এ মডেলগুলিকে প্রশিক্ষণ এবং স্থাপন করার জন্য, বিভিন্ন ML এবং গভীর শিক্ষার কাঠামো ব্যবহার করে।

SageMaker-এর সাথে Hugging Face ইন্টিগ্রেশন আপনাকে আপনার নিজের ডোমেন-নির্দিষ্ট ব্যবহারের ক্ষেত্রে স্কেলে Hugging Face মডেল তৈরি করতে দেয়।

এই পোস্টে, আমরা SageMaker-এ একটি কাস্টম হাগিং ফেস টেক্সট সামারিজার কীভাবে তৈরি এবং স্থাপন করতে হয় তার একটি উদাহরণ দিয়ে আপনাকে নিয়ে চলেছি। আমরা এই উদ্দেশ্যে পেগাসাস [1] ব্যবহার করি, প্রথম ট্রান্সফরমার-ভিত্তিক মডেলটি বিশেষভাবে বিমূর্ত পাঠ্য সংক্ষিপ্তকরণের জন্য তৈরি একটি উদ্দেশ্যের উপর প্রাক-প্রশিক্ষিত। BERT একটি বাক্যে এলোমেলো শব্দগুলিকে মুখোশ করার জন্য প্রাক-প্রশিক্ষিত; বিপরীতে, পেগাসাসের প্রাক-প্রশিক্ষণের সময়, বাক্যগুলি একটি ইনপুট নথি থেকে মুখোশ করা হয়। মডেলটি তখন অনুপস্থিত বাক্যগুলিকে একটি একক আউটপুট ক্রম হিসাবে সমস্ত মুখোশহীন বাক্যগুলিকে প্রসঙ্গ হিসাবে ব্যবহার করে তৈরি করে, ফলস্বরূপ নথির একটি নির্বাহী সারাংশ তৈরি করে।

HuggingFace লাইব্রেরির নমনীয়তার জন্য ধন্যবাদ, আপনি সহজেই এই পোস্টে দেখানো কোডটিকে অন্যান্য ধরনের ট্রান্সফরমার মডেলের জন্য মানিয়ে নিতে পারেন, যেমন t5, BART এবং আরও অনেক কিছু।

একটি আলিঙ্গন মুখ মডেল ফাইন-টিউন করতে আপনার নিজস্ব ডেটাসেট লোড করুন

একটি CSV ফাইল থেকে একটি কাস্টম ডেটাসেট লোড করতে, আমরা ব্যবহার করি load_dataset ট্রান্সফরমার প্যাকেজ থেকে পদ্ধতি। আমরা ব্যবহার করে লোড করা ডেটাসেটে টোকেনাইজেশন প্রয়োগ করতে পারি datasets.Dataset.map ফাংশন দ্য map ফাংশন লোড করা ডেটাসেটের উপর পুনরাবৃত্তি করে এবং প্রতিটি উদাহরণে টোকেনাইজ ফাংশন প্রয়োগ করে। টোকেনাইজড ডেটাসেটটি মডেলটি সূক্ষ্ম-টিউনিংয়ের জন্য প্রশিক্ষকের কাছে প্রেরণ করা যেতে পারে। নিম্নলিখিত কোড দেখুন:

# Python
def tokenize(batch):
    tokenized_input = tokenizer(batch[args.input_column], padding='max_length', truncation=True, max_length=args.max_source)
    tokenized_target = tokenizer(batch[args.target_column], padding='max_length', truncation=True, max_length=args.max_target)
    tokenized_input['target'] = tokenized_target['input_ids']

    return tokenized_input
    

def load_and_tokenize_dataset(data_dir):
    for file in os.listdir(data_dir):
        dataset = load_dataset("csv", data_files=os.path.join(data_dir, file), split='train')
    tokenized_dataset = dataset.map(lambda batch: tokenize(batch), batched=True, batch_size=512)
    tokenized_dataset.set_format('numpy', columns=['input_ids', 'attention_mask', 'labels'])
    
    return tokenized_dataset

Hugging Face SageMaker অনুমানকারীর জন্য আপনার প্রশিক্ষণ স্ক্রিপ্ট তৈরি করুন

পোস্টে ব্যাখ্যা করা হয়েছে প্রাকৃতিক ভাষা প্রক্রিয়াজাতকরণ মডেলগুলি সহজ ও ত্বরান্বিত করতে এডাব্লুএস এবং আলিঙ্গন ফেস সহযোগিতা করে, SageMaker-এ একটি আলিঙ্গন মুখ মডেল প্রশিক্ষণ সহজ ছিল না. আমরা থেকে আলিঙ্গন মুখ অনুমানকারী ব্যবহার করে তা করতে পারেন সেজমেকার এসডিকে.

নিম্নলিখিত কোড স্নিপেট আমাদের ডেটাসেটে পেগাসাসকে সূক্ষ্ম-টিউন করে। এছাড়াও আপনি অনেক খুঁজে পেতে পারেন নমুনা নোটবুক যা আপনাকে বিভিন্ন ধরণের মডেলের ফাইন-টিউনিং এর মাধ্যমে গাইড করে, সরাসরি ট্রান্সফরমার গিটহাব রিপোজিটরিতে পাওয়া যায়। বিতরণ করা প্রশিক্ষণ সক্ষম করতে, আমরা ব্যবহার করতে পারি ডেটা সমান্তরাল লাইব্রেরি SageMaker-এ, যা HuggingFace Trainer API-তে তৈরি করা হয়েছে। ডেটা সমান্তরাল সক্ষম করতে, আমাদের সংজ্ঞায়িত করতে হবে distribution আমাদের আলিঙ্গন মুখ অনুমানকারী প্যারামিটার.

# Python
from sagemaker.huggingface import HuggingFace
# configuration for running training on smdistributed Data Parallel
distribution = {'smdistributed':{'dataparallel':{ 'enabled': True }}}
huggingface_estimator = HuggingFace(entry_point='train.py',
                                    source_dir='code',
                                    base_job_name='huggingface-pegasus',
                                    instance_type= 'ml.g4dn.16xlarge',
                                    instance_count=1,
                                    transformers_version='4.6',
                                    pytorch_version='1.7',
                                    py_version='py36',
                                    output_path=output_path,
                                    role=role,
                                    hyperparameters = {
                                        'model_name': 'google/pegasus-xsum',
                                        'epoch': 10,
                                        'per_device_train_batch_size': 2
                                    },
                                    distribution=distribution)
huggingface_estimator.fit({'train': training_input_path, 'validation': validation_input_path, 'test': test_input_path})

সর্বাধিক প্রশিক্ষণ ব্যাচের আকার যা আপনি কনফিগার করতে পারেন তা নির্ভর করে মডেলের আকার এবং ব্যবহৃত উদাহরণের GPU মেমরির উপর। SageMaker বিতরণকৃত প্রশিক্ষণ সক্ষম করা থাকলে, মোট ব্যাচের আকার প্রতিটি ডিভাইস/GPU জুড়ে বিতরণ করা প্রতিটি ব্যাচের সমষ্টি। যদি আমরা একটি ml.g4dn.xlarge উদাহরণের পরিবর্তে বিতরণ করা প্রশিক্ষণের সাথে একটি ml.g16dn.4xlarge ব্যবহার করি, তাহলে আমাদের কাছে একটি ml.g8dn.xlarge উদাহরণের (4 GPU) থেকে আট গুণ (1 GPU) মেমরি থাকে। ডিভাইস প্রতি ব্যাচের আকার একই থাকে, তবে আটটি ডিভাইস সমান্তরালভাবে প্রশিক্ষণ দিচ্ছে।

SageMaker সঙ্গে স্বাভাবিক হিসাবে, আমরা একটি তৈরি train.py স্ক্রিপ্ট মোডের সাথে ব্যবহার করার জন্য স্ক্রিপ্ট এবং প্রশিক্ষণের জন্য হাইপারপ্যারামিটার পাস করুন। পেগাসাসের জন্য নিম্নলিখিত কোড স্নিপেট মডেলটি লোড করে এবং ট্রান্সফরমার ব্যবহার করে প্রশিক্ষণ দেয় Trainer শ্রেণী:

# Python
from transformers import (
    AutoModelForSeq2SeqLM,
    AutoTokenizer,
    Seq2SeqTrainer,
    Seq2seqTrainingArguments
)

model = AutoModelForSeq2SeqLM.from_pretrained(model_name).to(device)
    
training_args = Seq2seqTrainingArguments(
    output_dir=args.model_dir,
    num_train_epochs=args.epoch,
    per_device_train_batch_size=args.train_batch_size,
    per_device_eval_batch_size=args.eval_batch_size,
    warmup_steps=args.warmup_steps,
    weight_decay=args.weight_decay,
    logging_dir=f"{args.output_data_dir}/logs",
    logging_strategy='epoch',
    evaluation_strategy='epoch',
    saving_strategy='epoch',
    adafactor=True,
    do_train=True,
    do_eval=True,
    do_predict=True,
    save_total_limit = 3,
    load_best_model_at_end=True,
    metric_for_best_model='eval_loss'
    # With the goal to deploy the best checkpoint to production
    # it is important to set load_best_model_at_end=True,
    # this makes sure that the last model is saved at the root
    # of the model_dir” directory
)
    
trainer = Seq2SeqTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset['train'],
    eval_dataset=dataset['validation']
)

trainer.train()
trainer.save_model()

# Get rid of unused checkpoints inside the container to limit the model.tar.gz size
os.system(f"rm -rf {args.model_dir}/checkpoint-*/")

সম্পূর্ণ কোড পাওয়া যায় GitHub.

সেজমেকারে প্রশিক্ষিত আলিঙ্গন ফেস মডেলটি স্থাপন করুন

হাগিং ফেস-এর আমাদের বন্ধুরা ট্রান্সফরমার মডেলগুলির জন্য সেজমেকারের অনুমান আগের চেয়ে সহজ করেছে ধন্যবাদ সেজমেকার হাগিং ফেস ইনফারেন্স টুলকিট. আপনি কেবলমাত্র এনভায়রনমেন্ট ভেরিয়েবল সেট আপ করে পূর্বে প্রশিক্ষিত মডেলটি সরাসরি স্থাপন করতে পারেন "HF_TASK":"summarization" (নির্দেশের জন্য, দেখুন পেগাসাস মডেল), নির্বাচন করা স্থাপন করুন, এবং তারপর নির্বাচন আমাজন সেজমেকার, একটি অনুমান স্ক্রিপ্ট লিখতে প্রয়োজন ছাড়া.

যাইহোক, আপনার যদি কিছু নির্দিষ্ট উপায়ের প্রয়োজন হয় ভবিষ্যদ্বাণী তৈরি বা পোস্টপ্রসেস করার জন্য, যেমন বিভিন্ন টেক্সট জেনারেশন প্যারামিটারের তালিকার উপর ভিত্তি করে বেশ কিছু সারাংশ সাজেশন তৈরি করা, আপনার নিজের ইনফারেন্স স্ক্রিপ্ট লেখা দরকারী এবং তুলনামূলকভাবে সহজবোধ্য হতে পারে:

# Python
# inference.py script

import os
import json
import torch
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

def model_fn(model_dir):
    # Create the model and tokenizer and load weights
    # from the previous training Job, passed here through "model_dir"
    # that is reflected in HuggingFaceModel "model_data"
    tokenizer = AutoTokenizer.from_pretrained(model_dir)
    model = AutoModelForSeq2SeqLM.from_pretrained(model_dir).to(device).eval()
    
    model_dict = {'model':model, 'tokenizer':tokenizer}
    
    return model_dict
        

def predict_fn(input_data, model_dict):
    # Return predictions/generated summaries
    # using the loaded model and tokenizer on input_data
    text = input_data.pop('inputs')
    parameters_list = input_data.pop('parameters_list', None)
    
    tokenizer = model_dict['tokenizer']
    model = model_dict['model']

    # Parameters may or may not be passed    
    input_ids = tokenizer(text, truncation=True, padding='longest', return_tensors="pt").input_ids.to(device)
    
    if parameters_list:
        predictions = []
        for parameters in parameters_list:
            output = model.generate(input_ids, **parameters)
            predictions.append(tokenizer.batch_decode(output, skip_special_tokens=True))
    else:
        output = model.generate(input_ids)
        predictions = tokenizer.batch_decode(output, skip_special_tokens=True)
    
    return predictions
    
    
def input_fn(request_body, request_content_type):
    # Transform the input request to a dictionary
    request = json.loads(request_body)
    return request

পূর্ববর্তী কোডে দেখানো হয়েছে, SageMaker-এ HuggingFace-এর জন্য এই ধরনের একটি অনুমান স্ক্রিপ্ট শুধুমাত্র নিম্নলিখিত টেমপ্লেট ফাংশনগুলির প্রয়োজন:

  • মডেল_ফএন () - প্রশিক্ষণের কাজ শেষে কী সংরক্ষণ করা হয়েছিল তার বিষয়বস্তু পড়ে SM_MODEL_DIR, অথবা একটি বিদ্যমান মডেল ওজন ডিরেক্টরি থেকে একটি tar.gz ফাইল হিসাবে সংরক্ষিত আমাজন সিম্পল স্টোরেজ সার্ভিস (Amazon S3)। এটি প্রশিক্ষিত মডেল এবং সংশ্লিষ্ট টোকেনাইজার লোড করতে ব্যবহৃত হয়।
  • ইনপুট_ফএন () - শেষ পয়েন্টে করা একটি অনুরোধ থেকে প্রাপ্ত ডেটা ফর্ম্যাট করে।
  • পূর্বাভাস_ফএন () - এর আউটপুটকে কল করে model_fn() (মডেল এবং টোকেনাইজার) এর আউটপুটে অনুমান চালানোর জন্য input_fn() (ফরম্যাট করা ডেটা)।

ঐচ্ছিকভাবে, আপনি একটি তৈরি করতে পারেন output_fn() এর আউটপুট ব্যবহার করে অনুমান বিন্যাসের জন্য ফাংশন predict_fn(), যা আমরা এই পোস্টে প্রদর্শন করিনি।

তারপরে আমরা প্রশিক্ষিত আলিঙ্গন ফেস মডেলটিকে তার সম্পর্কিত অনুমান স্ক্রিপ্ট সহ সেজমেকার ব্যবহার করে স্থাপন করতে পারি আলিঙ্গন মুখ সেজমেকার মডেল শ্রেণী:

# Python
from sagemaker.huggingface import HuggingFaceModel

model = HuggingFaceModel(model_data=huggingface_estimator.model_data,
                     role=role,
                     framework_version='1.7',
                     py_version='py36',
                     entry_point='inference.py',
                     source_dir='code')
                     
predictor = model.deploy(initial_instance_count=1,
                         instance_type='ml.g4dn.xlarge'
                         )

স্থাপন করা মডেল পরীক্ষা করুন

এই ডেমো জন্য, আমরা মডেল প্রশিক্ষণ মহিলাদের ই-কমার্স পোশাক পর্যালোচনা ডেটাসেট, এতে পোশাকের নিবন্ধের পর্যালোচনা রয়েছে (যা আমরা ইনপুট পাঠ্য হিসাবে বিবেচনা করি) এবং তাদের সম্পর্কিত শিরোনাম (যা আমরা সারসংক্ষেপ হিসাবে বিবেচনা করি)। আমরা অনুপস্থিত শিরোনাম সহ নিবন্ধগুলি সরিয়ে দেওয়ার পরে, ডেটাসেটে 19,675টি পর্যালোচনা রয়েছে৷ পাঁচটি যুগের জন্য সেই নিবন্ধগুলির 70% সমন্বিত একটি প্রশিক্ষণ সেটে পেগাসাস মডেলটিকে ফাইন-টিউনিং করতে একটি ml.p3.5x বড় উদাহরণে প্রায় 3.16 ঘন্টা সময় লেগেছে।

তারপরে আমরা মডেলটি স্থাপন করতে পারি এবং পরীক্ষার সেট থেকে কিছু উদাহরণ ডেটা দিয়ে এটি পরীক্ষা করতে পারি। নীচে একটি সোয়েটার বর্ণনা করার একটি উদাহরণ পর্যালোচনা রয়েছে:

# Python
Review Text
"I ordered this sweater in green in petite large. The color and knit is beautiful and the shoulders and body fit comfortably; however, the sleeves were very long for a petite. I roll them, and it looks okay but would have rather had a normal petite length sleeve."

Original Title
"Long sleeves"

Rating
3

SageMaker এন্ডপয়েন্টে হোস্ট করা আমাদের কাস্টম ইনফারেন্স স্ক্রিপ্টের জন্য ধন্যবাদ, আমরা বিভিন্ন টেক্সট জেনারেশন প্যারামিটার সহ এই পর্যালোচনার জন্য বেশ কয়েকটি সারাংশ তৈরি করতে পারি। উদাহরণস্বরূপ, আমরা শেষ বিন্দুকে বিভিন্ন দৈর্ঘ্যের শাস্তি নির্দিষ্ট করে খুব সংক্ষিপ্ত থেকে মাঝারিভাবে দীর্ঘ সারাংশ তৈরি করতে বলতে পারি (দৈর্ঘ্যের শাস্তি যত ছোট হবে, উত্পন্ন সারাংশ তত কম হবে)। নিম্নলিখিত কিছু প্যারামিটার ইনপুট উদাহরণ, এবং পরবর্তী মেশিন-উত্পন্ন সারাংশ:

# Python
inputs = {
    "inputs":[
"I ordered this sweater in green in petite large. The color and knit is   beautiful and the shoulders and body fit comfortably; however, the sleeves were very long for a petite. I roll them, and it looks okay but would have rather had a normal petite length sleeve."
    ],

    "parameters_list":[
        {
            "length_penalty":2
        },
	{
            "length_penalty":1
        },
	{
            "length_penalty":0.6
        },
        {
            "length_penalty":0.4
        }
    ]

result = predictor.predict(inputs)
print(result)

[
    ["Beautiful color and knit but sleeves are very long for a petite"],
    ["Beautiful sweater, but sleeves are too long for a petite"],
    ["Cute, but sleeves are long"],
    ["Very long sleeves"]
]

আপনি কোন সারাংশ পছন্দ করেন? প্রথম জেনারেট করা শিরোনামটি এক চতুর্থাংশ শব্দের সাথে পর্যালোচনা সম্পর্কে সমস্ত গুরুত্বপূর্ণ তথ্য ক্যাপচার করে। বিপরীতে, শেষটি সোয়েটারের সবচেয়ে গুরুত্বপূর্ণ বৈশিষ্ট্যের উপর ফোকাস করতে শুধুমাত্র তিনটি শব্দ ব্যবহার করে (মূল পর্যালোচনার দৈর্ঘ্যের 1/10তমের কম)।

উপসংহার

আপনি আপনার কাস্টম ডেটাসেটে একটি টেক্সট সামারাইজারকে সূক্ষ্ম-টিউন করতে পারেন এবং এই সহজ উদাহরণের মাধ্যমে সেজমেকারে উৎপাদনে স্থাপন করতে পারেন GitHub। অতিরিক্ত নমুনা নোটবুক সেজমেকারে হাগিং ফেস মডেলগুলিকে প্রশিক্ষণ এবং স্থাপন করার জন্যও উপলব্ধ।

বরাবরের মতো, AWS প্রতিক্রিয়া স্বাগত জানায়। কোন মন্তব্য বা প্রশ্ন জমা দিন.

তথ্যসূত্র

[১] পেগাসাস: বিমূর্ত সংক্ষিপ্তসারের জন্য এক্সট্রাক্টেড গ্যাপ-বাক্য সহ প্রাক-প্রশিক্ষণ


লেখক সম্পর্কে

Fine-tune and deploy a summarizer model using the Hugging Face Amazon SageMaker containers bringing your own script PlatoBlockchain Data Intelligence. Vertical Search. Ai. ভিক্টর মালেসেভিচ AWS পেশাদার পরিষেবা সহ একজন মেশিন লার্নিং ইঞ্জিনিয়ার, প্রাকৃতিক ভাষা প্রক্রিয়াকরণ এবং MLOps সম্পর্কে উত্সাহী৷ তিনি গ্রাহকদের সাথে কাজ করে AWS-এ উৎপাদনের জন্য চ্যালেঞ্জিং ডিপ লার্নিং মডেল তৈরি করতে এবং রাখতে। তার অবসর সময়ে, তিনি বন্ধুদের সাথে এক গ্লাস রেড ওয়াইন এবং কিছু পনির ভাগ করে নিতে উপভোগ করেন।

Fine-tune and deploy a summarizer model using the Hugging Face Amazon SageMaker containers bringing your own script PlatoBlockchain Data Intelligence. Vertical Search. Ai.আমনা নাজমী AWS প্রফেশনাল সার্ভিসের সাথে একজন ডেটা সায়েন্টিস্ট। তিনি গ্রাহকদের বিগ ডেটা এবং কৃত্রিম বুদ্ধিমত্তা প্রযুক্তির মাধ্যমে ব্যবসায়িক মূল্য এবং ডেটা থেকে অন্তর্দৃষ্টি ট্যাপ করতে সাহায্য করার বিষয়ে উত্সাহী৷ তার অবসর সময়ে, তিনি বাগান করা এবং নতুন জায়গায় ভ্রমণ উপভোগ করেন।

সময় স্ট্যাম্প:

থেকে আরো এডাব্লুএস মেশিন লার্নিং

রিয়েল এস্টেট ব্রোকারেজ ফার্ম জন এল. স্কট আমাজন টেক্সট্র্যাক্ট ব্যবহার করে বাড়ির মালিকদের সম্পত্তির কাজ থেকে জাতিগতভাবে সীমাবদ্ধ ভাষা স্ট্রাইক করে

উত্স নোড: 1725296
সময় স্ট্যাম্প: অক্টোবর 17, 2022