| | import torch |
| | from qwen_vl_utils import process_vision_info |
| |
|
| | KOREAN_MORAL_EMOTION_THRESHOLDS = { |
| | 'other_condemning': 0.75, |
| | 'other_praising': 0.22, |
| | 'other_suffering': 0.56, |
| | 'self_conscious': 0.26, |
| | 'non_moral_emotion': 0.19, |
| | 'neutral': 0.55 |
| | } |
| |
|
| | ENGLISH_MORAL_EMOTION_THRESHOLDS = { |
| | 'other_condemning': 0.63, |
| | 'other_praising': 0.54, |
| | 'other_suffering': 0.52, |
| | 'self_conscious': 0.17, |
| | 'non_moral_emotion': 0.24, |
| | 'neutral': 0.59 |
| | } |
| |
|
| | MORAL_EMOTION_MAPPING = { |
| | 'other_condemning': 'Other-condemning', |
| | 'other_praising': 'Other-praising', |
| | 'other_suffering': 'Other-suffering', |
| | 'self_conscious': 'Self-conscious', |
| | 'non_moral_emotion': 'Non-moral emotion', |
| | 'neutral': 'Neutral' |
| | } |
| |
|
| | KOREAN_EMOTION_DESCRIPTION = { |
| | 'Other-condemning': 'λΆλ
Έ, κ²½λ©Έ, νμ€ λ±κ³Ό κ°μ΄ νμΈμ λΉλνλ κ°μ ', |
| | 'Other-praising': 'κ°ν, κ°μ¬, κ²½μΈκ° λ±κ³Ό κ°μ΄ νμΈμ μΉμ°¬νλ κ°μ ', |
| | 'Other-suffering': 'μ°λ―Ό, λμ λ±κ³Ό κ°μ΄ νμΈμ 곡κ°νλ κ°μ ', |
| | 'Self-conscious': 'μμΉμ¬, μ£μ±
κ°, λΉνΉκ° λ±κ³Ό κ°μ΄ μμ μ λΆμ μ μΌλ‘ νκ°νλ κ°μ ', |
| | 'Non-moral emotion': 'λλ €μ, λλΌμ, κΈ°μ¨, λκ΄μ£Όμ λ±κ³Ό κ°μ΄ κ°μ μ΄ μμ§λ§ λ€λ₯Έ λλκ°μ κΈ°μ€μ μνμ§ μλ κ°μ ', |
| | 'Neutral': 'κ°μ μ΄ μκ±°λ κ±°μ μλ μ€λ¦½μ μΈ μΉ΄ν
κ³ λ¦¬' |
| | } |
| |
|
| | ENGLISH_EMOTION_DESCRIPTION = { |
| | 'Other-condemning': 'Emotions that condemn others, such as anger, contempt, or disgust.', |
| | 'Other-praising': 'Emotions that praise others, such as admiration, gratitude, or awe.', |
| | 'Other-suffering': 'Emotions of empathy for the suffering of others, such as compassion, or sympathy.', |
| | 'Self-conscious': 'Emotions that negatively evaluate oneself, such as shame, guilt, or embarrassment.', |
| | 'Non-moral emotion': 'Emotions that are emotional but not one of the other emotions, such as fear, surprise, joy, optimism, etc.', |
| | 'Neutral': 'A neutral category with no or few emotions.' |
| | } |
| |
|
| | def get_prompt(emotion, korean=True): |
| | emotion = MORAL_EMOTION_MAPPING[emotion] |
| | if korean: |
| | system_prompt = f""" |
| | λΉμ μ βλλκ°μ β λΆμΌμ λν μ λ¬Έκ°μ
λλ€. μ£Όμ΄μ§λ ν
μ€νΈμ μ΄λ―Έμ§μ λνλλ λλκ°μ μ΄ {emotion} μΈμ§μ μ¬λΆλ₯Ό λΆλ₯νμΈμ. {emotion} μ λ€μκ³Ό κ°μ΄ μ μ ν μ μμ΅λλ€. |
| | |
| | 1. {emotion}: {KOREAN_EMOTION_DESCRIPTION[emotion]} |
| | |
| | μ£Όμ΄μ§λ λ°μ΄ν°κ° {emotion} μ λλκ°μ μ λνλ΄λμ§ True νΉμ False λ‘ λΆλ₯νκ³ , λ΅μ ν λλ λΉμ μ μΆκ°μ μΈ μ€λͺ
μμ΄ True νΉμ False λ‘λ§ λ΅νμΈμ. |
| | """ |
| |
|
| | message_gpt = """ |
| | μ£Όμ΄μ§ Headline Textμ Imageμ λͺ¨λμμ λνλ λλκ°μ μ {emotion} μ΄μΌ? |
| | μΆκ°μ μΈ μ€λͺ
μμ΄ λλκ°μ μ΄ {emotion} μΈμ§ μ¬λΆλ§ True νΉμ False λ‘ λ€μκ³Ό κ°μ΄ λ΅λ³ν΄μ€. |
| | {λ΅} |
| | """ |
| |
|
| | return system_prompt, message_gpt |
| | |
| | system_prompt = f""" |
| | You are an AI expert in 'moral emotions'. Classify whether the moral emotion in the given text and image is {emotion}. {emotion} can be defined as follows. |
| | |
| | 1. {emotion}: {ENGLISH_EMOTION_DESCRIPTION[emotion]} |
| | |
| | Classify the given data as True or False to indicate the moral emotion of {emotion} and answer only True or False without your further explanation. |
| | """ |
| |
|
| | message_gpt = """ |
| | Is the moral emotion shown in both the given headline text and image {emotion}? |
| | Without further explanation, just answer True or False whether the moral emotion is {emotion}. |
| | {Answer} |
| | """ |
| |
|
| | return system_prompt, message_gpt |
| |
|
| | def format_data(sample, target_emotion, korean=True): |
| | system, message = get_prompt(target_emotion, korean) |
| | return {"messages": [ |
| | { |
| | "role": "system", |
| | "content": [{"type": "text", "text": system}], |
| | }, |
| | { |
| | "role": "user", |
| | "content": [ |
| | { |
| | "type": "text", |
| | "text": message + '\n' + sample["title"], |
| | },{ |
| | "type": "image", |
| | "image": sample["thumbnail"], |
| | } |
| | ], |
| | } |
| | ], |
| | "id": sample['id'], |
| | "label": 'True' if sample['human_gold_label'] == target_emotion else 'False', |
| | } |
| |
|
| |
|
| | def collate_fn(examples, processor, device, label2id, train=True): |
| | |
| | texts = [processor.apply_chat_template(example["messages"], tokenize=False) for example in examples] |
| | image_inputs = [process_vision_info(example["messages"])[0] for example in examples] |
| | ids = [example['id'] for example in examples] |
| | |
| | |
| | batch = processor(text=texts, images=image_inputs, return_tensors="pt", padding=True) |
| | batch = {k: v.to(device) for k, v in batch.items()} |
| |
|
| | batch['ids'] = ids |
| | |
| | if not train: return batch |
| |
|
| | cls_labels = [ |
| | int(label2id[ex['label']]) |
| | for ex in examples |
| | ] |
| | batch["labels"] = torch.tensor( |
| | cls_labels, |
| | dtype=torch.float16, |
| | device=device |
| | ).unsqueeze(1) |
| |
|
| | return batch |