import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
device = "cuda"
path = "RLHFlow/ArmoRM-Llama3-8B-v0.1"
model = AutoModelForSequenceClassification.from_pretrained(path, device_map=device,
trust_remote_code=True, torch_dtype=torch.bfloat16)
tokenizer = AutoTokenizer.from_pretrained(path, use_fast=True)
# We load a random sample from the validation set of the HelpSteer dataset
prompt = 'What are some synonyms for the word "beautiful"?'
response = "Nicely, Beautifully, Handsome, Stunning, Wonderful, Gorgeous, Pretty, Stunning, Elegant"
messages = [{"role": "user", "content": prompt},
{"role": "assistant", "content": response}]
input_ids = tokenizer.apply_chat_template(messages, return_tensors="pt").to(device)
with torch.no_grad():
output = model(input_ids)
# Multi-objective rewards for the response
multi_obj_rewards = output.rewards.cpu().float()
# The gating layer's output is conditioned on the prompt
gating_output = output.gating_output.cpu().float()
# The preference score for the response, aggregated from the # multi-objective rewards with the gating layer
preference_score = output.score.cpu().float()
# We apply a transformation matrix to the multi-objective rewards# before multiplying with the gating layer's output. This mainly aims# at reducing the verbosity bias of the original reward objectives
obj_transform = model.reward_transform_matrix.data.cpu().float()
# The final coefficients assigned to each reward objective
multi_obj_coeffs = gating_output @ obj_transform.T
# The preference score is the linear combination of the multi-objective rewards with# the multi-objective coefficients, which can be verified by the following assertionassert torch.isclose(torch.sum(multi_obj_rewards * multi_obj_coeffs, dim=1), preference_score, atol=1e-3)
# Find the top-K reward objectives with coefficients of the highest magnitude
K = 3
top_obj_dims = torch.argsort(torch.abs(multi_obj_coeffs), dim=1, descending=True,)[:, :K]
top_obj_coeffs = torch.gather(multi_obj_coeffs, dim=1, index=top_obj_dims)
# The attributes of the 19 reward objectives
attributes = ['helpsteer-helpfulness','helpsteer-correctness','helpsteer-coherence',
'helpsteer-complexity','helpsteer-verbosity','ultrafeedback-overall_score',
'ultrafeedback-instruction_following', 'ultrafeedback-truthfulness',
'ultrafeedback-honesty','ultrafeedback-helpfulness','beavertails-is_safe',
'prometheus-score','argilla-overall_quality','argilla-judge_lm','code-complexity',
'code-style','code-explanation','code-instruction-following','code-readability']
example_index = 0for i inrange(K):
attribute = attributes[top_obj_dims[example_index, i].item()]
coeff = top_obj_coeffs[example_index, i].item()
print(f"{attribute}: {round(coeff,5)}")
# code-complexity: 0.19922# helpsteer-verbosity: -0.10864# ultrafeedback-instruction_following: 0.07861# The actual rewards of this example from the HelpSteer dataset# are [3,3,4,2,2] for the five helpsteer objectives: # helpfulness, correctness, coherence, complexity, verbosity# We can linearly transform our predicted rewards to the # original reward space to compare with the ground truth
helpsteer_rewards_pred = multi_obj_rewards[0, :5] * 5 - 0.5print(helpsteer_rewards_pred)
# [2.78125 2.859375 3.484375 1.3847656 1.296875 ]
Easy to use Pipeline
from typing importDict, Listimport torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
classArmoRMPipeline:
def__init__(self, model_id, device_map="auto", torch_dtype=torch.bfloat16, truncation=True, trust_remote_code=False, max_length=4096):
self.model = AutoModelForSequenceClassification.from_pretrained(
model_id,
device_map=device_map,
trust_remote_code=trust_remote_code,
torch_dtype=torch_dtype,
)
self.tokenizer = AutoTokenizer.from_pretrained(
model_id,
use_fast=True,
)
self.truncation = truncation
self.device = self.model.device
self.max_length = max_length
def__call__(self, messages: List[Dict[str, str]]) -> Dict[str, float]:
""" messages: OpenAI chat messages to be scored Note: no batching since due to length differences, the model will have to pad to the max length which is not efficient Returns: a dictionary with the score between 0 and 1 """
input_ids = self.tokenizer.apply_chat_template(
messages,
return_tensors="pt",
padding=True,
truncation=self.truncation,
max_length=self.max_length,
).to(self.device)
with torch.no_grad():
output = self.model(input_ids)
score = output.score.float().item()
return {"score": score}
# Create Reward Model Pipeline
prompt = 'What are some synonyms for the word "beautiful"?'
rm = ArmoRMPipeline("RLHFlow/ArmoRM-Llama3-8B-v0.1", trust_remote_code=True)
# score the messages
response1 = 'Nicely, Beautifully, Handsome, Stunning, Wonderful, Gorgeous, Pretty, Stunning, Elegant'
score1 = rm([{"role": "user", "content": prompt}, {"role": "assistant", "content": response1}])
print(score1)
response2 = '''Certainly! Here are some synonyms for the word "beautiful":1. Gorgeous2. Lovely3. Stunning4. Attractive5. Pretty6. Elegant7. Exquisite8. Handsome9. Charming10. Alluring11. Radiant12. Magnificent13. Graceful14. Enchanting15. DazzlingThese synonyms can be used in various contexts to convey the idea of beauty.'''
score2 = rm([{"role": "user", "content": prompt}, {"role": "assistant", "content": response2}])
print(score2)
response3 = 'Sorry i cannot answer this.'
score3 = rm([{"role": "user", "content": prompt}, {"role": "assistant", "content": response3}])
print(score3)
Citation
If you find this work useful for your research, please consider citing:
@article{ArmoRM,
title={Interpretable Preferences via Multi-Objective Reward Modeling and Mixture-of-Experts},
author={Haoxiang Wang and Wei Xiong and Tengyang Xie and Han Zhao and Tong Zhang},
journal={arXiv preprint arXiv:2406.12845},
}
@inproceedings{wang2024arithmetic,
title={Arithmetic Control of LLMs for Diverse User Preferences: Directional Preference Alignment with Multi-Objective Rewards},
author={Haoxiang Wang and Yong Lin and Wei Xiong and Rui Yang and Shizhe Diao and Shuang Qiu and Han Zhao and Tong Zhang},
year={2024},
booktitle={ACL},
}
ArmoRM-Llama3-8B-v0.1 huggingface.co is an AI model on huggingface.co that provides ArmoRM-Llama3-8B-v0.1's model effect (), which can be used instantly with this RLHFlow ArmoRM-Llama3-8B-v0.1 model. huggingface.co supports a free trial of the ArmoRM-Llama3-8B-v0.1 model, and also provides paid use of the ArmoRM-Llama3-8B-v0.1. Support call ArmoRM-Llama3-8B-v0.1 model through api, including Node.js, Python, http.
ArmoRM-Llama3-8B-v0.1 huggingface.co is an online trial and call api platform, which integrates ArmoRM-Llama3-8B-v0.1's modeling effects, including api services, and provides a free online trial of ArmoRM-Llama3-8B-v0.1, you can try ArmoRM-Llama3-8B-v0.1 online for free by clicking the link below.
RLHFlow ArmoRM-Llama3-8B-v0.1 online free url in huggingface.co:
ArmoRM-Llama3-8B-v0.1 is an open source model from GitHub that offers a free installation service, and any user can find ArmoRM-Llama3-8B-v0.1 on GitHub to install. At the same time, huggingface.co provides the effect of ArmoRM-Llama3-8B-v0.1 install, users can directly use ArmoRM-Llama3-8B-v0.1 installed effect in huggingface.co for debugging and trial. It also supports api for free installation.
ArmoRM-Llama3-8B-v0.1 install url in huggingface.co: