mymusise / ChatGLM-Tuning

基于ChatGLM-6B + LoRA的Fintune方案
MIT License
3.71k stars 443 forks source link

没有看到RLHF的代码 #175

Open dongdongrj opened 1 year ago

dongdongrj commented 1 year ago

你好,下载repo后,在modeling_chatglm.py中没有看到RLHF和训练RM及PPO训练RL的代码。在read_me中明明说是和chatGPT一样的技术,支持RLHF的,请问是怎么情况啊。

jackaduma commented 1 year ago

人家不是写了 todo 吗? 你都不看 README 嘛

Skywalker-Harrison commented 1 year ago

This has not been done.

jackaduma commented 1 year ago

训练 Reward Model 需要执行 SeqCLS 这个Task: huggingface 的 transformer 提供 "AutoModelForSequenceClassification" 这个类。但是 ChatGLM 只有 "ChatGLMForConditionalGeneration" 这个类。所以暂时没法训练 Reward model,等ChatGLM自己放出代码,或者huggingface 集成 ChatGLM吧

suc16 commented 1 year ago

训练 Reward Model 需要执行 SeqCLS 这个Task: huggingface 的 transformer 提供 "AutoModelForSequenceClassification" 这个类。但是 ChatGLM 只有 "ChatGLMForConditionalGeneration" 这个类。所以暂时没法训练 Reward model,等ChatGLM自己放出代码,或者huggingface 集成 ChatGLM吧

transformers似乎没有计划支持chatglm,所以直接用trl去rlhf不太现实

dongdongrj commented 1 year ago

训练 Reward Model 需要执行 SeqCLS 这个Task: huggingface 的 transformer 提供 "AutoModelForSequenceClassification" 这个类。但是 ChatGLM 只有 "ChatGLMForConditionalGeneration" 这个类。所以暂时没法训练 Reward model,等ChatGLM自己放出代码,或者huggingface 集成 ChatGLM吧

我就是想看看,是如何训练RM及如何用RM再训练RL的。大量的无标签的数据格式是怎么样的,这个你知道吗。

dongdongrj commented 1 year ago

训练 Reward Model 需要执行 SeqCLS 这个Task: huggingface 的 transformer 提供 "AutoModelForSequenceClassification" 这个类。但是 ChatGLM 只有 "ChatGLMForConditionalGeneration" 这个类。所以暂时没法训练 Reward model,等ChatGLM自己放出代码,或者huggingface 集成 ChatGLM吧

transformers似乎没有计划支持chatglm,所以直接用trl去rlhf不太现实

你说的trl是什么?迁移学习吗

suc16 commented 1 year ago

训练 Reward Model 需要执行 SeqCLS 这个Task: huggingface 的 transformer 提供 "AutoModelForSequenceClassification" 这个类。但是 ChatGLM 只有 "ChatGLMForConditionalGeneration" 这个类。所以暂时没法训练 Reward model,等ChatGLM自己放出代码,或者huggingface 集成 ChatGLM吧

transformers似乎没有计划支持chatglm,所以直接用trl去rlhf不太现实

你说的trl是什么?迁移学习吗

一个rl的库,适配huggingface的模型。

dongdongrj commented 1 year ago

这个真不错啊,谢谢。 想不到colossalai竟然支持了chatglm

suc16 commented 1 year ago

这个真不错啊,谢谢。 想不到colossalai竟然支持了chatglm

那个yynil大佬比较强,他改的太多了,根本不可能合入主分支。不过是真的能跑啊,我已经跑通了。

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

suc16 commented 1 year ago

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

suc16 commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

suc16 commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

mymusise commented 1 year ago

训练 Reward Model 需要执行 SeqCLS 这个Task: huggingface 的 transformer 提供 "AutoModelForSequenceClassification" 这个类。但是 ChatGLM 只有 "ChatGLMForConditionalGeneration" 这个类。所以暂时没法训练 Reward model,等ChatGLM自己放出代码,或者huggingface 集成 ChatGLM吧

transformers似乎没有计划支持chatglm,所以直接用trl去rlhf不太现实

用trl需要对trainer做下修改,最近在调这块,跑是跑通了,但是最后结果和yynil大佬的差不太多 🤣

这两天整理下代码我先扔个PR出来 Orz

suc16 commented 1 year ago

训练 Reward Model 需要执行 SeqCLS 这个Task: huggingface 的 transformer 提供 "AutoModelForSequenceClassification" 这个类。但是 ChatGLM 只有 "ChatGLMForConditionalGeneration" 这个类。所以暂时没法训练 Reward model,等ChatGLM自己放出代码,或者huggingface 集成 ChatGLM吧

transformers似乎没有计划支持chatglm,所以直接用trl去rlhf不太现实

用trl需要对trainer做下修改,最近在调这块,跑是跑通了,但是最后结果和yynil大佬的差不太多 🤣

这两天整理下代码我先扔个PR出来 Orz

大佬👍

suc16 commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

mymusise commented 1 year ago

我先贴下TRL Trainer需要的改动,主要有两块:

import torch

from trl.trainer.ppo_trainer import logprobs_from_logits, PreTrainedModelWrapper, PPODecorators, PPOTrainer

class CustomPPOTrainer(PPOTrainer):

    def pad_input_ids(self, ids, max_length):
        _ids = torch.ones(max_length, dtype=torch.int8) * self.model.config.pad_token_id
        _ids[:len(ids)] = ids
        return _ids

    def prepare_model_inputs(self, queries: torch.Tensor, responses: torch.Tensor):
        input_ids = [torch.cat([q, r]) for q, r in zip(queries, responses)]
        max_length = max([len(ids) for ids in input_ids])
        input_data = self.data_collator(
            [{
                "input_ids": self.pad_input_ids(ids, max_length)
            } for ids in input_ids]
        ).to(self.current_device)

        input_data.pop("labels", None)  # we don't want to compute LM losses

        return input_data

    @PPODecorators.empty_cuda_cache()
    def batched_forward_pass(
        self,
        model: PreTrainedModelWrapper,
        queries: torch.Tensor,
        responses: torch.Tensor,
        model_inputs: dict,
    ):
        """
        Calculate model outputs in multiple batches.

        Args:
            queries (`torch.LongTensor`):
                List of tensors containing the encoded queries, shape (`batch_size`, `query_length`)
            responses (`torch.LongTensor`):
                List of tensors containing the encoded responses, shape (`batch_size`, `response_length`)
        Returns:
            (tuple):
                - all_logprobs (`torch.FloatTensor`): Log probabilities of the responses,
                    shape (`batch_size`, `response_length`)
                - all_ref_logprobs (`torch.FloatTensor`): Log probabilities of the responses,
                    shape (`batch_size`, `response_length`)
                - all_values (`torch.FloatTensor`): Values of the responses, shape (`batch_size`, `response_length`)
        """
        bs = len(queries)
        fbs = self.config.mini_batch_size
        all_logprobs = []
        all_logits = []
        all_masks = []
        all_values = []

        for i in range(int(bs / fbs)):
            input_kwargs = {key: value[i * fbs : (i + 1) * fbs] for key, value in model_inputs.items()}
            query_batch = queries[i * fbs : (i + 1) * fbs]
            response_batch = responses[i * fbs : (i + 1) * fbs]
            logits, _, values = model(**input_kwargs)

            if self.is_encoder_decoder:
                input_ids = input_kwargs["decoder_input_ids"]
                attention_mask = input_kwargs["decoder_attention_mask"]
            else:
                input_ids = input_kwargs["input_ids"]
                attention_mask = input_kwargs["attention_mask"]

            logprobs = logprobs_from_logits(logits[:, :-1, :], input_ids[:, 1:])
            masks = torch.zeros_like(input_ids)
            for i, ids in enumerate(input_ids):
                start_i = (ids == self.model.config.bos_token_id).nonzero()
                end_i = (ids == self.model.config.eos_token_id).nonzero()
                if len(end_i):
                    end_i = end_i[0][0] + 1
                else:
                    end_i = None
                masks[i][start_i:end_i] = 1

            all_logits.append(logits)
            all_values.append(values.rot90())
            all_logprobs.append(logprobs)
            all_masks.append(masks)

        return (
            torch.cat(all_logprobs),
            torch.cat(all_logits)[:, :-1],
            torch.cat(all_values)[:, :-1],
            torch.cat(all_masks)[:, :-1],
        )
dongdongrj commented 1 year ago

我先贴下TRL Trainer需要的改动,主要有两块:

  • prepare_model_inputs 做下right padding
  • batched_forward_pass 时候的mask要改改(chatglm的attention_mask是2D的,要转换下)
import torch

from trl.trainer.ppo_trainer import logprobs_from_logits, PreTrainedModelWrapper, PPODecorators, PPOTrainer

class CustomPPOTrainer(PPOTrainer):

    def pad_input_ids(self, ids, max_length):
        _ids = torch.ones(max_length, dtype=torch.int8) * self.model.config.pad_token_id
        _ids[:len(ids)] = ids
        return _ids

    def prepare_model_inputs(self, queries: torch.Tensor, responses: torch.Tensor):
        input_ids = [torch.cat([q, r]) for q, r in zip(queries, responses)]
        max_length = max([len(ids) for ids in input_ids])
        input_data = self.data_collator(
            [{
                "input_ids": self.pad_input_ids(ids, max_length)
            } for ids in input_ids]
        ).to(self.current_device)

        input_data.pop("labels", None)  # we don't want to compute LM losses

        return input_data

    @PPODecorators.empty_cuda_cache()
    def batched_forward_pass(
        self,
        model: PreTrainedModelWrapper,
        queries: torch.Tensor,
        responses: torch.Tensor,
        model_inputs: dict,
    ):
        """
        Calculate model outputs in multiple batches.

        Args:
            queries (`torch.LongTensor`):
                List of tensors containing the encoded queries, shape (`batch_size`, `query_length`)
            responses (`torch.LongTensor`):
                List of tensors containing the encoded responses, shape (`batch_size`, `response_length`)
        Returns:
            (tuple):
                - all_logprobs (`torch.FloatTensor`): Log probabilities of the responses,
                    shape (`batch_size`, `response_length`)
                - all_ref_logprobs (`torch.FloatTensor`): Log probabilities of the responses,
                    shape (`batch_size`, `response_length`)
                - all_values (`torch.FloatTensor`): Values of the responses, shape (`batch_size`, `response_length`)
        """
        bs = len(queries)
        fbs = self.config.mini_batch_size
        all_logprobs = []
        all_logits = []
        all_masks = []
        all_values = []

        for i in range(int(bs / fbs)):
            input_kwargs = {key: value[i * fbs : (i + 1) * fbs] for key, value in model_inputs.items()}
            query_batch = queries[i * fbs : (i + 1) * fbs]
            response_batch = responses[i * fbs : (i + 1) * fbs]
            logits, _, values = model(**input_kwargs)

            if self.is_encoder_decoder:
                input_ids = input_kwargs["decoder_input_ids"]
                attention_mask = input_kwargs["decoder_attention_mask"]
            else:
                input_ids = input_kwargs["input_ids"]
                attention_mask = input_kwargs["attention_mask"]

            logprobs = logprobs_from_logits(logits[:, :-1, :], input_ids[:, 1:])
            masks = torch.zeros_like(input_ids)
            for i, ids in enumerate(input_ids):
                start_i = (ids == self.model.config.bos_token_id).nonzero()
                end_i = (ids == self.model.config.eos_token_id).nonzero()
                if len(end_i):
                    end_i = end_i[0][0] + 1
                else:
                    end_i = None
                masks[i][start_i:end_i] = 1

            all_logits.append(logits)
            all_values.append(values.rot90())
            all_logprobs.append(logprobs)
            all_masks.append(masks)

        return (
            torch.cat(all_logprobs),
            torch.cat(all_logits)[:, :-1],
            torch.cat(all_values)[:, :-1],
            torch.cat(all_masks)[:, :-1],
        )

mark一下,后面有问题找你讨论。

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

suc16 commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

继续finetuning就可以了,你说的这种增强数学能力的项目很多的,https://github.com/yongzhuo/chatglm-maths @mymusise 大佬,我又发现了一个实现了ppo的库。。。还是trl的供参考。。。

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

我感觉就算是训练这三步,也是基于之前预训练好的chatGLM吧?微调SFT的模型是chatglm-6b,PPO阶段的actor也是chatglm-6b,不知道我的理解对不对。这样的话其实就是在原有pretrained的基础上增加新的能力。

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

我感觉就算是训练这三步,也是基于之前预训练好的chatGLM吧?微调SFT的模型是chatglm-6b,PPO阶段的actor也是chatglm-6b,不知道我的理解对不对。这样的话其实就是在原有pretrained的基础上增加新的能力。这样的话和直接做finetuning又有什么区别呢。

suc16 commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

我感觉就算是训练这三步,也是基于之前预训练好的chatGLM吧?微调SFT的模型是chatglm-6b,PPO阶段的actor也是chatglm-6b,不知道我的理解对不对。这样的话其实就是在原有pretrained的基础上增加新的能力。

对的,你看vicuna就是llama上构建的,llama没啥中文能力但是vicuna中文很好。

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

我感觉就算是训练这三步,也是基于之前预训练好的chatGLM吧?微调SFT的模型是chatglm-6b,PPO阶段的actor也是chatglm-6b,不知道我的理解对不对。这样的话其实就是在原有pretrained的基础上增加新的能力。

对的,你看vicuna就是llama上构建的,llama没啥中文能力但是vicuna中文很好。

那直接用prompt集合来finetuning和完成三步训练有什么区别呢。

suc16 commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

我感觉就算是训练这三步,也是基于之前预训练好的chatGLM吧?微调SFT的模型是chatglm-6b,PPO阶段的actor也是chatglm-6b,不知道我的理解对不对。这样的话其实就是在原有pretrained的基础上增加新的能力。

对的,你看vicuna就是llama上构建的,llama没啥中文能力但是vicuna中文很好。

那直接用prompt集合来finetuning和完成三步训练有什么区别呢。

已知chatgpt最强,已知chatgpt用了rlhf,推论rlhf比简单sft强(手动狗头)

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

我感觉就算是训练这三步,也是基于之前预训练好的chatGLM吧?微调SFT的模型是chatglm-6b,PPO阶段的actor也是chatglm-6b,不知道我的理解对不对。这样的话其实就是在原有pretrained的基础上增加新的能力。

对的,你看vicuna就是llama上构建的,llama没啥中文能力但是vicuna中文很好。

那直接用prompt集合来finetuning和完成三步训练有什么区别呢。

已知chatgpt最强,已知chatgpt用了rlhf,推论rlhf比简单sft强(手动狗头)

OK

dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

我感觉就算是训练这三步,也是基于之前预训练好的chatGLM吧?微调SFT的模型是chatglm-6b,PPO阶段的actor也是chatglm-6b,不知道我的理解对不对。这样的话其实就是在原有pretrained的基础上增加新的能力。

对的,你看vicuna就是llama上构建的,llama没啥中文能力但是vicuna中文很好。

那直接用prompt集合来finetuning和完成三步训练有什么区别呢。

已知chatgpt最强,已知chatgpt用了rlhf,推论rlhf比简单sft强(手动狗头)

只有第一阶段和第二阶段的数据是需要人类标注的吧?第三阶段的数据是self-instruct产生的?

suc16 commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

我感觉就算是训练这三步,也是基于之前预训练好的chatGLM吧?微调SFT的模型是chatglm-6b,PPO阶段的actor也是chatglm-6b,不知道我的理解对不对。这样的话其实就是在原有pretrained的基础上增加新的能力。

对的,你看vicuna就是llama上构建的,llama没啥中文能力但是vicuna中文很好。

那直接用prompt集合来finetuning和完成三步训练有什么区别呢。

已知chatgpt最强,已知chatgpt用了rlhf,推论rlhf比简单sft强(手动狗头)

只有第一阶段和第二阶段的数据是需要人类标注的吧?第三阶段的数据是self-instruct产生的?

第三阶段数据不用单独标

mymusise commented 1 year ago

训练 Reward Model 需要执行 SeqCLS 这个Task: huggingface 的 transformer 提供 "AutoModelForSequenceClassification" 这个类。但是 ChatGLM 只有 "ChatGLMForConditionalGeneration" 这个类。所以暂时没法训练 Reward model,等ChatGLM自己放出代码,或者huggingface 集成 ChatGLM吧

确实,不过可以对ChatGLM的lm_headforward方法做下修改,也能用,我先贴下我在用的代码(我担心又继续鸽🤔 ):

import torch
import transformers

from torch import nn
from typing import Optional, Tuple
from transformers.modeling_outputs import SequenceClassifierOutputWithPast
from torch.nn.utils import skip_init

config = transformers.AutoConfig.from_pretrained(
    "THUDM/chatglm-6b", trust_remote_code=True
)
config.auto_map = {
    "AutoModel": "modeling_chatglm.ChatGLMModel",
    "AutoModelForAudioClassification": "modeling_chatglm.ChatGLMPreTrainedModel",
}

base_cls = transformers.AutoModel.from_config(config=config, trust_remote_code=True)

ml_cls = transformers.AutoModelForAudioClassification.from_config(
    config=config, trust_remote_code=True
)

class RewardModel(ml_cls.__class__):
    def forward(
        self,
        input_ids: Optional[torch.Tensor] = None,
        position_ids: Optional[torch.Tensor] = None,
        attention_mask: Optional[torch.Tensor] = None,
        past_key_values: Optional[Tuple[torch.FloatTensor]] = None,
        inputs_embeds: Optional[torch.Tensor] = None,
        labels: Optional[torch.Tensor] = None,
        use_cache: Optional[bool] = None,
        output_attentions: Optional[bool] = None,
        output_hidden_states: Optional[bool] = None,
        return_dict: Optional[bool] = None,
    ):
        use_cache = use_cache if use_cache is not None else self.config.use_cache
        return_dict = (
            return_dict if return_dict is not None else self.config.use_return_dict
        )

        transformer_outputs = self.transformer(
            input_ids=input_ids,
            position_ids=position_ids,
            attention_mask=attention_mask,
            past_key_values=past_key_values,
            inputs_embeds=inputs_embeds,
            use_cache=use_cache,
            output_attentions=output_attentions,
            output_hidden_states=output_hidden_states,
            return_dict=return_dict,
        )

        hidden_states = transformer_outputs[0]

        lm_logits = self.lm_head(hidden_states).permute(1, 0, 2)

        if input_ids is not None:
            batch_size = input_ids.shape[0]
        else:
            batch_size = inputs_embeds.shape[0]

        if self.config.pad_token_id is None:
            sequence_lengths = -1
        else:
            if input_ids is not None:
                sequence_lengths = (
                    torch.ne(input_ids, self.config.pad_token_id).sum(-1) - 1
                ).to(lm_logits.device)
            else:
                sequence_lengths = -1

        pooled_logits = lm_logits[
            torch.arange(batch_size, device=lm_logits.device), sequence_lengths
        ]

        loss = None

        if not return_dict:
            output = (lm_logits,) + transformer_outputs[1:]
            return ((loss,) + output) if loss is not None else output

        return SequenceClassifierOutputWithPast(
            loss=loss,
            logits=pooled_logits,
            past_key_values=transformer_outputs.past_key_values,
            hidden_states=transformer_outputs.hidden_states,
            attentions=transformer_outputs.attentions,
        )

# init
reward_model = RewardModel.from_pretrained("THUDM/chatglm-6b", load_in_8bit=True, device_map='auto')
reward_model.lm_head = torch.nn.Linear(reward_model.config.hidden_size, 1, bias=False, dtype=torch.half, device=reward_model.device).to(reward_model.device)

#  add peft
# ..

然后对应的trainer

from transformers import Trainer, TrainingArguments
from torch import nn

class RewardTrainer(Trainer):
    def compute_loss(self, model, inputs, return_outputs=False):
        rewards_j = model(input_ids=inputs["input_ids_j"])[0]
        rewards_k = model(input_ids=inputs["input_ids_k"])[0]
        loss = -nn.functional.logsigmoid(rewards_j - rewards_k).mean()
        if return_outputs:
            return loss, {"rewards_j": rewards_j, "rewards_k": rewards_k}
        return loss
dongdongrj commented 1 year ago

这个里面有说明无标签数据格式了吗

这个里面有说明无标签数据格式了吗

有,RM数据集每条 PROMPT + 正样本 + 负样本,PPO阶段的数据集每条 PROMPT

微调SFT的时候还是5万个prompt吧? PPO阶段如何搜集大量的prompt呢?chatGPT学习了万亿级的数据,难道都是通过prompt吗?是不是通过什么方法来产生大量的prompt?

先跑通流程吧(手动狗头)

我就是想整明白PPO阶段的数据格式是怎样的。

和SFT阶段复用就行,参考https://zhuanlan.zhihu.com/p/622361287

你好,我看了这个内容。其实我想要做的事情是,既能保留现有chatGLM-6B的能力又可以增加特定领域的能力。chatglm-6B hub上提供了finetuning,只需构造alpaca指令集合。但是只适用于特定领域的问题在一个小的分布上。假如特定领的问题集合非常大,人工没有办法构造如此庞大的prompt集合。那么我既要保留chatGLM-6B的现有能力,又要学习新的特定领域能力。通过官方提供的finetuning是没有办法做到的。我想实现这样的功能应该怎么做呢。PPO阶段依然是学习prompt,怎么才能构造如此大量的prompt呢。

不理解你的意思啊,prompt是instruction+input,你有种子instruction和海量input构造prompt不是很简单吗?即使你手上只有一个领域图谱,你也可以像hit最新的huatuo模型一样大量造问答对啊。

你说的海量的input是领域内的知识吧,比如我想增强chatGLM-6B的代码能力,我有大量的代码,这个可以做为input吗?我不太明白你说的input是什么。

我想表达的是,既保留chatglm的对话能力,又要增强它的代码能力。我需要重新训练那三步吗?还是只要finetuning?

我感觉就算是训练这三步,也是基于之前预训练好的chatGLM吧?微调SFT的模型是chatglm-6b,PPO阶段的actor也是chatglm-6b,不知道我的理解对不对。这样的话其实就是在原有pretrained的基础上增加新的能力。

对的,你看vicuna就是llama上构建的,llama没啥中文能力但是vicuna中文很好。

那直接用prompt集合来finetuning和完成三步训练有什么区别呢。

已知chatgpt最强,已知chatgpt用了rlhf,推论rlhf比简单sft强(手动狗头)

只有第一阶段和第二阶段的数据是需要人类标注的吧?第三阶段的数据是self-instruct产生的?

第三阶段数据不用单独标

你在跑yynil的代码时,有没有碰到这个错误。看起来是多GPU的问题,我是colab上只有一个GPU。 torch.distributed.elastic.multiprocessing.errors.ChildFailedError:

taofennanhai commented 1 year ago

训练 Reward Model 需要执行 SeqCLS 这个Task: huggingface 的 transformer 提供 "AutoModelForSequenceClassification" 这个类。但是 ChatGLM 只有 "ChatGLMForConditionalGeneration" 这个类。所以暂时没法训练 Reward model,等ChatGLM自己放出代码,或者huggingface 集成 ChatGLM吧

确实,不过可以对ChatGLM的lm_headforward方法做下修改,也能用,我先贴下我在用的代码(我担心又继续鸽🤔 ):

import torch
import transformers

from torch import nn
from typing import Optional, Tuple
from transformers.modeling_outputs import SequenceClassifierOutputWithPast
from torch.nn.utils import skip_init

config = transformers.AutoConfig.from_pretrained(
    "THUDM/chatglm-6b", trust_remote_code=True
)
config.auto_map = {
    "AutoModel": "modeling_chatglm.ChatGLMModel",
    "AutoModelForAudioClassification": "modeling_chatglm.ChatGLMPreTrainedModel",
}

base_cls = transformers.AutoModel.from_config(config=config, trust_remote_code=True)

ml_cls = transformers.AutoModelForAudioClassification.from_config(
    config=config, trust_remote_code=True
)

class RewardModel(ml_cls.__class__):
    def forward(
        self,
        input_ids: Optional[torch.Tensor] = None,
        position_ids: Optional[torch.Tensor] = None,
        attention_mask: Optional[torch.Tensor] = None,
        past_key_values: Optional[Tuple[torch.FloatTensor]] = None,
        inputs_embeds: Optional[torch.Tensor] = None,
        labels: Optional[torch.Tensor] = None,
        use_cache: Optional[bool] = None,
        output_attentions: Optional[bool] = None,
        output_hidden_states: Optional[bool] = None,
        return_dict: Optional[bool] = None,
    ):
        use_cache = use_cache if use_cache is not None else self.config.use_cache
        return_dict = (
            return_dict if return_dict is not None else self.config.use_return_dict
        )

        transformer_outputs = self.transformer(
            input_ids=input_ids,
            position_ids=position_ids,
            attention_mask=attention_mask,
            past_key_values=past_key_values,
            inputs_embeds=inputs_embeds,
            use_cache=use_cache,
            output_attentions=output_attentions,
            output_hidden_states=output_hidden_states,
            return_dict=return_dict,
        )

        hidden_states = transformer_outputs[0]

        lm_logits = self.lm_head(hidden_states).permute(1, 0, 2)

        if input_ids is not None:
            batch_size = input_ids.shape[0]
        else:
            batch_size = inputs_embeds.shape[0]

        if self.config.pad_token_id is None:
            sequence_lengths = -1
        else:
            if input_ids is not None:
                sequence_lengths = (
                    torch.ne(input_ids, self.config.pad_token_id).sum(-1) - 1
                ).to(lm_logits.device)
            else:
                sequence_lengths = -1

        pooled_logits = lm_logits[
            torch.arange(batch_size, device=lm_logits.device), sequence_lengths
        ]

        loss = None

        if not return_dict:
            output = (lm_logits,) + transformer_outputs[1:]
            return ((loss,) + output) if loss is not None else output

        return SequenceClassifierOutputWithPast(
            loss=loss,
            logits=pooled_logits,
            past_key_values=transformer_outputs.past_key_values,
            hidden_states=transformer_outputs.hidden_states,
            attentions=transformer_outputs.attentions,
        )

# init
reward_model = RewardModel.from_pretrained("THUDM/chatglm-6b", load_in_8bit=True, device_map='auto')
reward_model.lm_head = torch.nn.Linear(reward_model.config.hidden_size, 1, bias=False, dtype=torch.half, device=reward_model.device).to(reward_model.device)

#  add peft
# ..

然后对应的trainer

from transformers import Trainer, TrainingArguments
from torch import nn

class RewardTrainer(Trainer):
    def compute_loss(self, model, inputs, return_outputs=False):
        rewards_j = model(input_ids=inputs["input_ids_j"])[0]
        rewards_k = model(input_ids=inputs["input_ids_k"])[0]
        loss = -nn.functional.logsigmoid(rewards_j - rewards_k).mean()
        if return_outputs:
            return loss, {"rewards_j": rewards_j, "rewards_k": rewards_k}
        return loss

有试过trlx库吗

suc16 commented 1 year ago

https://github.com/Miraclemarvel55/ChatGLM-RLHF 在chatglm论坛看到的另一个库,可以参考一下

dongdongrj commented 1 year ago

https://github.com/Miraclemarvel55/ChatGLM-RLHF 在chatglm论坛看到的另一个库,可以参考一下

这一个是没有做SFT,直接做了RLHF。这样好吗?我认为还是把三步都做了比较好。

mymusise commented 1 year ago

有试过trlx库吗

嗯,最近在试ilql,trl那套reward model不太好train,搞了几版都reward收敛不了 😭 用那些现成的sentiment模型作为reward model,虽然收敛但训出来的基本就成傻子了 😶‍🌫️

cristianohello commented 1 year ago

@mymusise 期待加入新功能!

yanni-code commented 1 year ago

看到一个信息: chatglm-6b 在原始代码的基础上进行了部分调整,以支持ChatGPT训练pipeline,具体实现可参考:sunzeyeah/RLHF.