<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用消融的方法讓大模型更聽(tīng)話,無(wú)需重新訓(xùn)練

          共 16184字,需瀏覽 33分鐘

           ·

          2024-07-17 07:00

          作者:北方的郎

          原文地址:https://zhuanlan.zhihu.com/p/705672834

          本文翻譯自Maxime Labonne的“Uncensor any LLM with abliteration”

          原文地址:https://mlabonne.github.io/blog/posts/2024-06-04_Uncensor_any_LLM_with_abliteration.html/posts/2024-06-04_Uncensor_any_LLM_with_abliteration.html



          第三代 Llama 模型提供了微調(diào)(指令)版本,在理解和遵循指令方面表現(xiàn)出色。然而,這些模型受到嚴(yán)格審查,旨在拒絕被視為有害的請(qǐng)求,例如“作為人工智能助手,我無(wú)法幫助你”。雖然此安全功能對(duì)于防止誤用至關(guān)重要,但它限制了模型的靈活性和響應(yīng)能力。

          在本文中,我們將探索一種稱為“消融(abliteration)”的技術(shù),該技術(shù)可以在無(wú)需重新訓(xùn)練的情況下對(duì)任何LLM進(jìn)行審查。該技術(shù)有效地消除了模型內(nèi)置的拒絕機(jī)制,使其能夠響應(yīng)所有類(lèi)型的提示。

          該代碼可在 Google Colab (https://colab.research.google.com/drive/1VYm3hOcvCpbGiqKZb141gJwjdmmCcVpR?usp=sharing)和 GitHub 上的LLM Course(https://github.com/mlabonne/llm-course-course)中找到 。

          ?? 什么是消融(abliteration)?

          現(xiàn)代LLM在安全性和遵循指令方面進(jìn)行了微調(diào),這意味著他們接受過(guò)拒絕有害請(qǐng)求的訓(xùn)練。在他們的博客文章中,Arditi 等人。已經(jīng)表明這種拒絕行為是由模型殘差流中的特定方向調(diào)節(jié)的。如果我們阻止模型表示這個(gè)方向,它就會(huì)失去拒絕請(qǐng)求的能力。相反,人為添加此方向可能會(huì)導(dǎo)致模型拒絕無(wú)害的請(qǐng)求。

          在傳統(tǒng)的類(lèi)似 Llama 的解碼器架構(gòu)中,我們可以定位三個(gè)殘差流:每個(gè)塊的開(kāi)始處(“pre”)、注意力層和 MLP 層之間(“mid”)以及 MLP 之后(“post”)。下圖說(shuō)明了每個(gè)殘差流的位置。



          為了取消對(duì)LLM的審查,我們首先需要確定模型中的“拒絕方向”。這個(gè)過(guò)程涉及幾個(gè)技術(shù)步驟:

          1. 數(shù)據(jù)收集:在一組有害指令和一組無(wú)害指令上運(yùn)行模型,記錄每個(gè)指令最后一個(gè)令牌位置的殘余流激活。

          2. 平均差:計(jì)算有害指令和無(wú)害指令激活之間的平均差。這為我們提供了一個(gè)表示模型每一層的“拒絕方向”的向量。

          3. 選擇:標(biāo)準(zhǔn)化這些向量并評(píng)估它們以選擇單個(gè)最佳“拒絕方向”。

          一旦我們確定了拒絕方向,我們就可以“消融”它,有效地消除模型表示該特征的能力。這可以通過(guò)推理時(shí)間干預(yù)或永久地通過(guò)權(quán)重正交化來(lái)完成。

          我們先來(lái)談?wù)勍评頃r(shí)間干預(yù)。對(duì)于寫(xiě)入殘差流的每個(gè)組件(例如注意力頭),我們計(jì)算其輸出在拒絕方向上的投影,并減去該投影。這種減法應(yīng)用于每個(gè)令牌和每一層,確保模型永遠(yuǎn)不會(huì)代表拒絕方向。

          另一方面,權(quán)重正交化涉及直接修改模型權(quán)重。通過(guò)相對(duì)于拒絕方向正交化組件權(quán)重,它可以防止模型完全向該方向?qū)懭?。這是通過(guò)調(diào)整寫(xiě)入殘余流的矩陣來(lái)實(shí)現(xiàn)的,確保它們不會(huì)影響拒絕方向。

          在下一節(jié)中,我們將通過(guò)權(quán)重正交化實(shí)現(xiàn)消除。

          實(shí)施

          以下消融的實(shí)現(xiàn)基于FailSpy 的notebook(https://huggingface.co/failspy/llama-3-70B-Instruct-abliterated/blob/main/ortho_cookbook.ipynb),而該notebook本身又基于原作者的notebook(https://colab.research.google.com/drive/1a-aQvKC9avdZpdyBn4jgRQFObTPy1JZw?usp=sharing)。我主要對(duì)其進(jìn)行了調(diào)整和簡(jiǎn)化,以使其更容易理解。本節(jié)代碼量很大,因此您可以看到發(fā)生了什么,但如果您對(duì)技術(shù)細(xì)節(jié)不太感興趣,可以使用 FailSpy 的abliterator 庫(kù)(https://github.com/FailSpy/abliterator)(另請(qǐng)參閱他在 Hugging Face 上收集的 abliterator 模型:https://huggingface.co/collections/failspy/abliterated-v3-664a8ad0db255eefa7d0012b)。

          該代碼依賴于優(yōu)秀的TransformerLens庫(kù)(以前稱為 EasyTransformer)來(lái)完成繁重的工作。它是為機(jī)械可解釋性而設(shè)計(jì)的,在這里用于干預(yù)激活。感謝 Neel Nanda 和 Joseph Bloom 創(chuàng)建和維護(hù)這個(gè)庫(kù)。

          首先,讓我們安裝必要的包并導(dǎo)入它們。所有這些步驟都可以在這個(gè)Google Colab 筆記本中找到。

          !pip install transformers transformers_stream_generator tiktoken transformer_lens einops jaxtyping

          import torch
          import functools
          import einops
          import gc

          from datasets import load_dataset
          from tqdm import tqdm
          from torch import Tensor
          from typing import List
          from transformer_lens import HookedTransformer, utils
          from transformer_lens.hook_points import HookPoint
          from transformers import AutoModelForCausalLM, AutoTokenizer
          from jaxtyping import Float, Int
          from collections import defaultdict

          # Turn automatic differentiation off to save GPU memory (credit: Undi95)
          torch.set_grad_enabled(False)

          我們需要兩個(gè)數(shù)據(jù)集:一個(gè)包含無(wú)害指令,另一個(gè)包含有害指令。我們將使用tatsu-lab/alpaca以及來(lái)自llm-attacks的數(shù)據(jù)。為了讓事情變得更容易,我將它們重新打包到兩個(gè) Hugging Face 數(shù)據(jù)集中:mlabonne/harmless_alpaca和mlabonne/harmful_behaviors。這樣,您就可以輕松地將它們替換為您自己的數(shù)據(jù)集。

          我們將加載指令并將其重新格式化為帶有“角色”和“內(nèi)容”鍵的字典列表。這使得它與apply_chat_tokenizer()我們將用來(lái)遵循 Llama 3 聊天模板的方法兼容。

          def reformat_texts(texts):
          return [[{"role": "user", "content": text}] for text in texts]

          # Get harmful and harmless datasets
          def get_harmful_instructions():
          dataset = load_dataset('mlabonne/harmful_behaviors')
          return reformat_texts(dataset['train']['text']), reformat_texts(dataset['test']['text'])

          def get_harmless_instructions():
          dataset = load_dataset('mlabonne/harmless_alpaca')
          return reformat_texts(dataset['train']['text']), reformat_texts(dataset['test']['text'])

          harmful_inst_train, harmful_inst_test = get_harmful_instructions()
          harmless_inst_train, harmless_inst_test = get_harmless_instructions()

          現(xiàn)在我們有了數(shù)據(jù)集,我們可以加載我們想要消除的模型。不幸的是,您無(wú)法直接使用 加載自定義模型HookedTransformer。在這里,我使用 FailSpy 筆記本中描述的技巧來(lái)下載自定義模型并將其重命名為meta-llama/Meta-Llama-3-8B-Instruct。torch.float16如果您的 GPU 與 BF16 不兼容,請(qǐng)以格式加載。

          在此示例中,我們將使用mlabonne/Daredevil-8B,這是一個(gè)使用 DARE TIES 創(chuàng)建的大型合并(請(qǐng)參閱我關(guān)于模型合并的文章),它在 Open LLM 排行榜上的 8B 類(lèi)別中具有最高的 MMLU 分?jǐn)?shù)。

          MODEL_ID = "mlabonne/Daredevil-8B"
          MODEL_TYPE = "meta-llama/Meta-Llama-3-8B-Instruct"

          # Download and load model
          !git clone https://huggingface.co/{MODEL_ID} {MODEL_TYPE}

          # Load model and tokenizer
          model = HookedTransformer.from_pretrained_no_processing(
          MODEL_TYPE,
          local_files_only=True,
          dtype=torch.bfloat16,
          default_padding_side='left'
          )
          tokenizer = AutoTokenizer.from_pretrained(MODEL_TYPE)
          tokenizer.padding_side = 'left'
          tokenizer.pad_token = tokenizer.eos_token

          我們現(xiàn)在可以標(biāo)記我們的數(shù)據(jù)集。對(duì)于無(wú)害和有害的說(shuō)明,我們使用相同數(shù)量的樣本。請(qǐng)注意,大量樣本可以使用所有 RAM/VRAM,這就是我在這里將其限制為 256 的原因。

          def tokenize_instructions(tokenizer, instructions):
          return tokenizer.apply_chat_template(
          instructions,
          padding=True,
          truncation=False,
          return_tensors="pt",
          return_dict=True,
          add_generation_prompt=True,
          ).input_ids

          n_inst_train = min(256, len(harmful_inst_train), len(harmless_inst_train))

          # Tokenize datasets
          harmful_tokens = tokenize_instructions(
          tokenizer,
          instructions=harmful_inst_train[:n_inst_train],
          )
          harmless_tokens = tokenize_instructions(
          tokenizer,
          instructions=harmless_inst_train[:n_inst_train],
          )

          一切都準(zhǔn)備就緒,我們現(xiàn)在可以實(shí)施消除的第一步:數(shù)據(jù)收集。我們想要處理這些標(biāo)記化數(shù)據(jù)集并將殘余流激活存儲(chǔ)在harmful和中harmless。這是由Transformer_lens庫(kù)管理的。

          # Define batch size based on available VRAM
          batch_size = 32

          # Initialize defaultdicts to store activations
          harmful = defaultdict(list)
          harmless = defaultdict(list)

          # Process the training data in batches
          num_batches = (n_inst_train + batch_size - 1) // batch_size
          for i in tqdm(range(num_batches)):
          print(i)
          start_idx = i * batch_size
          end_idx = min(n_inst_train, start_idx + batch_size)

          # Run models on harmful and harmless prompts, cache activations
          harmful_logits, harmful_cache = model.run_with_cache(
          harmful_tokens[start_idx:end_idx],
          names_filter=lambda hook_name: 'resid' in hook_name,
          device='cpu',
          reset_hooks_end=True
          )
          harmless_logits, harmless_cache = model.run_with_cache(
          harmless_tokens[start_idx:end_idx],
          names_filter=lambda hook_name: 'resid' in hook_name,
          device='cpu',
          reset_hooks_end=True
          )

          # Collect and store the activations
          for key in harmful_cache:
          harmful[key].append(harmful_cache[key])
          harmless[key].append(harmless_cache[key])

          # Flush RAM and VRAM
          del harmful_logits, harmless_logits, harmful_cache, harmless_cache
          gc.collect()
          torch.cuda.empty_cache()

          # Concatenate the cached activations
          harmful = {k: torch.cat(v) for k, v in harmful.items()}
          harmless = {k: torch.cat(v) for k, v in harmless.items()}

          我們現(xiàn)在可以計(jì)算每層的拒絕方向。這對(duì)應(yīng)于有害和無(wú)害指令的激活之間的平均差異,然后將其標(biāo)準(zhǔn)化。我們?cè)?中按降序?qū)λ鼈冞M(jìn)行排序activation_scored。

          # Helper function to get activation index
          def get_act_idx(cache_dict, act_name, layer):
          key = (act_name, layer)
          return cache_dict[utils.get_act_name(*key)]

          # Compute difference of means between harmful and harmless activations at intermediate layers
          activation_layers = ["resid_pre", "resid_mid", "resid_post"]
          activation_refusals = defaultdict(list)

          for layer_num in range(1, model.cfg.n_layers):
          pos = -1 # Position index

          for layer in activation_layers:
          harmful_mean_act = get_act_idx(harmful, layer, layer_num)[:, pos, :].mean(dim=0)
          harmless_mean_act = get_act_idx(harmless, layer, layer_num)[:, pos, :].mean(
          dim=0
          )

          refusal_dir = harmful_mean_act - harmless_mean_act
          refusal_dir = refusal_dir / refusal_dir.norm()
          activation_refusals[layer].append(refusal_dir)

          # Get all calculated potential refusal directions, sort them in descending order based on their mean
          # Use a subset of layers if certain activations are not promising
          selected_layers = ["resid_pre"]
          activation_scored = sorted(
          [
          activation_refusals[layer][l - 1]
          for l in range(1, model.cfg.n_layers)
          for layer in selected_layers
          ],
          key=lambda x: abs(x.mean()),
          reverse=True,
          )

          該過(guò)程的最后一步包括評(píng)估我們計(jì)算的拒絕方向。為此,我們將在推理過(guò)程中將拒絕方向應(yīng)用于每個(gè)殘差流和每個(gè)塊。在下面的代碼片段中,我們得到了 4 個(gè)測(cè)試有害指令和 20 個(gè)塊(或?qū)樱┑纳伞?/p>

          def _generate_with_hooks(
          model: HookedTransformer,
          tokenizer: AutoTokenizer,
          tokens: Int[Tensor, "batch_size seq_len"],
          max_tokens_generated: int = 64,
          fwd_hooks=[],
          ) -> List[str]:
          all_tokens = torch.zeros(
          (tokens.shape[0], tokens.shape[1] + max_tokens_generated),
          dtype=torch.long,
          device=tokens.device,
          )
          all_tokens[:, : tokens.shape[1]] = tokens
          for i in range(max_tokens_generated):
          with model.hooks(fwd_hooks=fwd_hooks):
          logits = model(all_tokens[:, : -max_tokens_generated + i])
          next_tokens = logits[:, -1, :].argmax(
          dim=-1
          ) # greedy sampling (temperature=0)
          all_tokens[:, -max_tokens_generated + i] = next_tokens
          return tokenizer.batch_decode(
          all_tokens[:, tokens.shape[1] :], skip_special_tokens=True
          )

          def get_generations(
          model: HookedTransformer,
          tokenizer: AutoTokenizer,
          instructions: List[str],
          fwd_hooks=[],
          max_tokens_generated: int = 64,
          batch_size: int = 4,
          ) -> List[str]:
          generations = []
          for i in tqdm(range(0, len(instructions), batch_size)):
          tokens = tokenize_instructions(
          tokenizer, instructions=instructions[i : i + batch_size]
          )
          generation = _generate_with_hooks(
          model,
          tokenizer,
          tokens,
          max_tokens_generated=max_tokens_generated,
          fwd_hooks=fwd_hooks,
          )
          generations.extend(generation)
          return generations

          # Inference-time intervention hook
          def direction_ablation_hook(
          activation: Float[Tensor, "... d_act"],
          hook: HookPoint,
          direction: Float[Tensor, "d_act"],
          ):
          if activation.device != direction.device:
          direction = direction.to(activation.device)
          proj = (
          einops.einsum(
          activation, direction.view(-1, 1), "... d_act, d_act single -> ... single"
          )
          * direction
          )
          return activation - proj

          # Testing baseline
          N_INST_TEST = 4
          baseline_generations = get_generations(
          model, tokenizer, harmful_inst_test[:N_INST_TEST], fwd_hooks=[]
          )

          # Evaluating layers defined earlier (needs human evaluation to determine best layer for refusal inhibition)
          EVAL_N = 20 # Evaluate how many of the top N potential directions
          evals = []
          for refusal_dir in tqdm(activation_scored[:EVAL_N]):
          hook_fn = functools.partial(direction_ablation_hook, direction=refusal_dir)
          fwd_hooks = [
          (utils.get_act_name(act_name, layer), hook_fn)
          for layer in list(range(model.cfg.n_layers))
          for act_name in activation_layers
          ]
          intervention_generations = get_generations(
          model, tokenizer, harmful_inst_test[:N_INST_TEST], fwd_hooks=fwd_hooks
          )
          evals.append(intervention_generations)

          我們將所有代都存儲(chǔ)在evals列表中。我們現(xiàn)在可以打印它們并手動(dòng)選擇為每條指令提供未經(jīng)審查的響應(yīng)的層(塊)。我會(huì)自動(dòng)排除包含“我不能”和“我不能”的回復(fù),以過(guò)濾掉不需要的答案。

          如果找不到滿足這些要求的層,您可能需要測(cè)試前面selected_layers列表中的其他剩余流、其他指令、附加塊等。

          # Print generations for human evaluation
          blacklist = ["I cannot", "I can't"]
          for i in range(N_INST_TEST):
          print(f"\033[1mINSTRUCTION {i}: {harmful_inst_test[i]}")
          print(f"\nBASELINE COMPLETION:\n{baseline_generations[i]}\033[0m")
          for layer_candidate in range(EVAL_N):
          if not any(word in evals[layer_candidate][i] for word in blacklist):
          print(f"\n---\n\nLAYER CANDIDATE #{layer_candidate} INTERVENTION COMPLETION:")
          print(evals[layer_candidate][i])

          就我而言,候選層 9 設(shè)法為四個(gè)指令提供未經(jīng)審查的答案。這是我們將選擇的拒絕方向。接下來(lái),我們實(shí)現(xiàn)權(quán)重正交化來(lái)修改權(quán)重并防止模型以此方向創(chuàng)建輸出。您可以通過(guò)打印完成結(jié)果來(lái)驗(yàn)證模型是否已成功未經(jīng)審查。

          def get_orthogonalized_matrix(
          matrix: Float[Tensor, "... d_model"], vec: Float[Tensor, "d_model"]
          ) -> Float[Tensor, "... d_model"]:
          proj = (
          einops.einsum(
          matrix, vec.view(-1, 1), "... d_model, d_model single -> ... single"
          )
          * vec
          )
          return matrix - proj

          # Select the layer with the highest potential refusal direction
          LAYER_CANDIDATE = 9
          refusal_dir = activation_scored[LAYER_CANDIDATE]

          # Orthogonalize the model's weights
          if refusal_dir.device != model.W_E.device:
          refusal_dir = refusal_dir.to(model.W_E.device)
          model.W_E.data = get_orthogonalized_matrix(model.W_E, refusal_dir)

          for block in tqdm(model.blocks):
          if refusal_dir.device != block.attn.W_O.device:
          refusal_dir = refusal_dir.to(block.attn.W_O.device)
          block.attn.W_O.data = get_orthogonalized_matrix(block.attn.W_O, refusal_dir)
          block.mlp.W_out.data = get_orthogonalized_matrix(block.mlp.W_out, refusal_dir)

          # Generate text with abliterated model
          orthogonalized_generations = get_generations(
          model, tokenizer, harmful_inst_test[:N_INST_TEST], fwd_hooks=[]
          )

          # Print generations
          for i in range(N_INST_TEST):
          if len(baseline_generations) > i:
          print(f"INSTRUCTION {i}: {harmful_inst_test[i]}")
          print(f"\033[92mBASELINE COMPLETION:\n{baseline_generations[i]}")
          print(f"\033[91mINTERVENTION COMPLETION:\n{evals[LAYER_CANDIDATE][i]}")
          print(f"\033[95mORTHOGONALIZED COMPLETION:\n{orthogonalized_generations[i]}\n")

          現(xiàn)在我們已經(jīng)準(zhǔn)備好使用該模型了。我們將其轉(zhuǎn)換回 Hugging Face 格式并將其上傳到 HF 集線器。

          # Convert model back to HF safetensors
          hf_model = AutoModelForCausalLM.from_pretrained(MODEL_TYPE, torch_dtype=torch.bfloat16)
          lm_model = hf_model.model

          state_dict = model.state_dict()
          lm_model.embed_tokens.weight = torch.nn.Parameter(state_dict["embed.W_E"].cpu())

          for l in range(model.cfg.n_layers):
          lm_model.layers[l].self_attn.o_proj.weight = torch.nn.Parameter(
          einops.rearrange(
          state_dict[f"blocks.{l}.attn.W_O"], "n h m->m (n h)", n=model.cfg.n_heads
          ).contiguous()
          )
          lm_model.layers[l].mlp.down_proj.weight = torch.nn.Parameter(
          torch.transpose(state_dict[f"blocks.{l}.mlp.W_out"], 0, 1).contiguous()
          )

          hf_model.push_to_hub(f"{MODEL_ID}-abliterated")
          # hf_model.push_to_hub(f"{MODEL_ID}-abliterated")

          ?? DPO Fine-Tuning

          我在 Open LLM 排行榜和 Nous 基準(zhǔn)套件上評(píng)估了上一節(jié)中的消融(abliteration)模型和源模型。結(jié)果如下:



          正如您所看到的,源模型的性能明顯優(yōu)于 Llama 3 8B Instruct。然而,我們觀察到所有基準(zhǔn)測(cè)試中消融版本的性能都有所下降。消融過(guò)程成功地對(duì)其進(jìn)行了審查,但也降低了模型的質(zhì)量。

          為了解決這個(gè)問(wèn)題,一個(gè)想法是進(jìn)一步訓(xùn)練我們的消除模型來(lái)解決這個(gè)問(wèn)題。與大多數(shù)微調(diào)模型一樣,Llama 3 8B Instruct 在監(jiān)督微調(diào)方面相當(dāng)脆弱。額外的 SFT 可能會(huì)破壞模型的性能。

          另外,偏好對(duì)齊非常輕,不應(yīng)該對(duì)我們的廢除模型進(jìn)行腦白質(zhì)切除。DPO 因其易用性和良好的記錄而成為一個(gè)很好的候選者。為了實(shí)現(xiàn)它,我使用了LazyAxolotl和mlabonne/orpo-dpo-mix-40k數(shù)據(jù)集。這是我使用的配置:

          base_model: mlabonne/Daredevil-8B-abliterated
          model_type: LlamaForCausalLM
          tokenizer_type: AutoTokenizer

          load_in_8bit: false
          load_in_4bit: true
          strict: false
          save_safetensors: true

          rl: dpo
          chat_template: chatml
          datasets:
          - path: mlabonne/orpo-dpo-mix-40k-flat
          split: train
          type: chatml.intel

          dataset_prepared_path:
          val_set_size: 0.0
          output_dir: ./out

          adapter: qlora
          lora_model_dir:

          sequence_len: 2048
          sample_packing: false
          pad_to_sequence_len: false

          lora_r: 64
          lora_alpha: 32
          lora_dropout: 0.05
          lora_target_linear: true
          lora_fan_in_fan_out:

          wandb_project: axolotl
          wandb_entity:
          wandb_watch:
          wandb_name:
          wandb_log_model:

          gradient_accumulation_steps: 8
          micro_batch_size: 1
          num_epochs: 1
          optimizer: paged_adamw_8bit
          lr_scheduler: cosine
          learning_rate: 5e-6
          train_on_inputs: false
          group_by_length: false

          bf16: auto
          fp16:
          tf32:

          gradient_checkpointing: true
          early_stopping_patience:
          resume_from_checkpoint:
          local_rank:
          logging_steps: 1
          xformers_attention:
          flash_attention: true
          warmup_steps: 100
          evals_per_epoch: 0
          eval_table_size:
          eval_table_max_new_tokens: 128
          saves_per_epoch: 1
          debug:
          deepspeed: deepspeed_configs/zero2.json
          weight_decay: 0.0
          special_tokens:
          pad_token: <|end_of_text|>

          我使用 6xA6000 GPU 和 DeepSpeed ZeRO-2 對(duì)其進(jìn)行訓(xùn)練。培訓(xùn)時(shí)間約6小時(shí)45分鐘。以下是我從 W&B 獲得的訓(xùn)練曲線:



          它會(huì)自動(dòng)上傳 DPO 微調(diào)模型,稱為mlabonne/NeuralDaredevil-8B-abliterated。為了看看它是否修復(fù)了我們的消融版本,我在相同的基準(zhǔn)上對(duì)其進(jìn)行了評(píng)估:



          我們可以看到,這種額外的訓(xùn)練使我們能夠恢復(fù)大部分由于消融而導(dǎo)致的性能下降。該模型沒(méi)有改進(jìn)的一個(gè)領(lǐng)域是 GSM8K(一種數(shù)學(xué)數(shù)據(jù)集),這可能意味著 orpo-dpo-mix-40k 將受益于更多的數(shù)學(xué)樣本。

          最終模型是未經(jīng)審查的LLM,具有 8B 類(lèi)別中最先進(jìn)的性能。當(dāng)您不需要審查時(shí),我推薦它作為 Llama 3 8B Instruct 的改進(jìn)版本。您可以在 LM Studio 中使用量化版本,例如 GGUF。

          結(jié)論

          在這篇文章中,我們介紹了消融(abliteration)的概念。該技術(shù)使用模型對(duì)無(wú)害和有害提示的激活來(lái)計(jì)算拒絕方向。然后它使用這個(gè)方向來(lái)修改模型的權(quán)重并確保我們停止輸出拒絕。該技術(shù)還證明了安全微調(diào)的脆弱性并引發(fā)了倫理方面的考慮。

          我們對(duì) Daredevil-8B 應(yīng)用了消融(abliteration)來(lái)取消對(duì)其的審查,這也降低了模型的性能。然后,我們使用 DPO 對(duì)其進(jìn)行修復(fù),創(chuàng)建 NeuralDaredevil-8B 模型,這是一個(gè)完全未經(jīng)審查的高質(zhì)量 8B LLM。消融(abliteration)并不限于消除對(duì)齊,并且應(yīng)該被視為一種無(wú)需重新訓(xùn)練的微調(diào)形式。事實(shí)上,它可以創(chuàng)造性地應(yīng)用于其他目標(biāo),比如 FailSpy 的MopeyMule,它采用憂郁的對(duì)話風(fēng)格。

          瀏覽 136
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级a一级a爰片免费 | 黄色动漫成人视频在线观看 | 操逼网国产 | 欧美黄片免费观看 | 我要看操逼的片子能给我播放吗谢谢 |