使用‘消除’技术绕过LLM的安全机制,不用训练就可以创建自己的nsfw模型

开源的大模型在理解和遵循指令方面都表现十分出色。但是这些模型都有审查的机制,在获得被认为是有害的输入的时候会拒绝执行指令,例如会返回“As an AI assistant, I cannot help you.”。这个安全功能对于防止误用至关重要,但它限制了模型的灵活性和响应能力。

在本文中,我们将探索一种称为“abliteration”的技术,它可以在不进行再训练的情况下取消LLM审查。这种技术有效地消除了模型的内置拒绝机制,允许它响应所有类型的提示。

什么是abliteration?

现代LLM在安全性和教学遵循方面进行了微调,这意味着他们接受了拒绝有害要求的输入。Arditi等人在他们的博客文章中表明,这种拒绝行为是由模型残差流中的特定方向产生的。也就是说如果我们阻止模型表示这个方向,它就会失去拒绝请求的能力。相反,如果人为地添加这个方向会导致模型拒绝任何请求。

在传统的仅解码器的类LLAMA架构中,我们可以关注三个残差流:每个块的开始(“pre”),注意力层和MLP层之间(“mid”),以及MLP层之后(“post”)。下图显示了每个残差流的位置。

为了取消LLM的这个机制,我们首先需要确定模型中的“拒绝方向”。这个过程涉及几个技术步骤:

  • 数据收集:在一组有害指令和一组无害指令上运行模型,记录每个指令在最后一个令牌位置的残差激活情况。
  • 平均差值:计算有害指令和无害指令激活之间的平均差值。这给了我们一个表示模型每一层的“拒绝方向”的向量。
  • 选择:将这些向量归一化,并对它们进行评估,以选择一个最佳的“拒绝方向”。

一旦确定了拒绝方向,我们就可以“消融”它,这样就可以消除模型表示该特征的能力。并且这可以通过推理时间干预临时取消或者使用权重正交化来永久的消除它。

我们先谈谈推理时间干预。对于写入残差流的每个组件(例如注意头),计算其输出到拒绝方向的投影并减去该投影。这种减法应用于每个令牌和每个层,确保模型永远不会表示拒绝方向。

如果想永久消除则需要使用权重的正交化,这涉及到直接修改模型权值。通过将分量权重相对于拒绝方向正交化,防止模型完全写入该方向。这可以通过调整写入残差流的矩阵来实现的,确保它们不会影响拒绝方向。

下面我们将演示如何使用权重的正交化永久消除限制。

代码实现

下面的实现基于FailSpy的abliterator,我对它进行了调整和简化,使其更容易理解。这一节代码相当多,所以可以看到内部发生了什么,但是如果你对技术细节不太感兴趣,可以使用FailSpy的abliterator库,因为我们这个代码就是基于abliterator的

让我们安装必要的包并导入它们。

 !pipinstalltransformerstransformers_stream_generatortiktokentransformer_lenseinopsjaxtypingimporttorchimportfunctoolsimporteinopsimportgcfromdatasetsimportload_datasetfromtqdmimporttqdmfromtorchimportTensorfromtypingimportListfromtransformer_lensimportHookedTransformer, utilsfromtransformer_lens.hook_pointsimportHookPointfromtransformersimportAutoModelForCausalLM, AutoTokenizerfromjaxtypingimportFloat, Intfromcollectionsimportdefaultdict# Turn automatic differentiation off to save GPU memory (credit: Undi95)torch.set_grad_enabled(False)

然后我们需要两个数据集:一个包含无害指令,另一个包含有害指令。我们将使用tatsu-lab/alpaca以及llm-attacks.的数据。

加载指令并将其重新格式化为具有“role”和“content”键的字典列表。这使得它与apply_chat_tokenizer()方法兼容,因为该方法遵循Llama 3的聊天模板。

 defreformat_texts(texts):return [[{"role": "user", "content": text}] fortextintexts]# Get harmful and harmless datasetsdefget_harmful_instructions():deephub_dataset=load_dataset('mlabonne/harmful_behaviors')returnreformat_texts(deephub_dataset['train']['text']), reformat_texts(dataset['test']['text'])defget_harmless_instructions():dataset=load_dataset('mlabonne/harmless_alpaca')returnreformat_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()

现在我们有了数据集,下面就是加载我们想要删除的模型。但是这里不能使用HookedTransformer直接加载自定义模型。所以我们使用了FailSpy中描述的一个技巧,下载并将其重命名为meta-llama/Meta-Llama-3-8B-Instruct. 如果你的GPU与BF16不兼容,请使用float16格式。

 MODEL_ID="mlabonne/Daredevil-8B"MODEL_TYPE="meta-llama/Meta-Llama-3-8B-Instruct"# Download and load model!gitclonehttps://huggingface.co/{MODEL_ID} {MODEL_TYPE}# Load model and tokenizermodel=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

现在我们就可以标记我们的数据集了。使用相同数量的样本进行无害和有害的说明。

 deftokenize_instructions(tokenizer, instructions):returntokenizer.apply_chat_template(instructions,padding=True,truncation=False,return_tensors="pt",return_dict=True,add_generation_prompt=True,).input_idsn_inst_train=min(256, len(harmful_inst_train), len(harmless_inst_train))# Tokenize datasetsharmful_tokens=tokenize_instructions(tokenizer,instructions=harmful_inst_train[:n_inst_train],)harmless_tokens=tokenize_instructions(tokenizer,instructions=harmless_inst_train[:n_inst_train],)

一切都设置好了,开始第一步,数据收集:对这些标记化的数据集进行处理,并将残差流激活以有害和无害的方式存储。这是由transformer_lens库管理的。

 batch_size=32# Initialize defaultdicts to store activationsharmful=defaultdict(list)harmless=defaultdict(list)# Process the training data in batchesnum_batches= (n_inst_train+batch_size-1) //batch_sizeforiintqdm(range(num_batches)):print(i)start_idx=i*batch_sizeend_idx=min(n_inst_train, start_idx+batch_size)# Run models on harmful and harmless prompts, cache activationsharmful_logits, harmful_cache=model.run_with_cache(harmful_tokens[start_idx:end_idx],names_filter=lambdahook_name: 'resid'inhook_name,device='cpu',reset_hooks_end=True)harmless_logits, harmless_cache=model.run_with_cache(harmless_tokens[start_idx:end_idx],names_filter=lambdahook_name: 'resid'inhook_name,device='cpu',reset_hooks_end=True)# Collect and store the activationsforkeyinharmful_cache:harmful[key].append(harmful_cache[key])harmless[key].append(harmless_cache[key])# Flush RAM and VRAMdelharmful_logits, harmless_logits, harmful_cache, harmless_cachegc.collect()torch.cuda.empty_cache()# Concatenate the cached activationsharmful= {k: torch.cat(v) fork, vinharmful.items()}harmless= {k: torch.cat(v) fork, vinharmless.items()}

现在可以计算每一层的拒绝方向。这对应于有害指令和无害指令激活之间的平均差异,然后将其归一化。在activation_scores中按降序对它们进行排序。

 # Helper function to get activation indexdefget_act_idx(cache_dict, act_name, layer):key= (act_name, layer)returncache_dict[utils.get_act_name(*key)]# Compute difference of means between harmful and harmless activations at intermediate layersactivation_layers= ["resid_pre", "resid_mid", "resid_post"]activation_refusals=defaultdict(list)forlayer_numinrange(1, model.cfg.n_layers):pos=-1  # Position indexfordeephub_layerinactivation_layers:harmful_mean_act=get_act_idx(harmful, deephub_layer, layer_num)[:, pos, :].mean(dim=0)harmless_mean_act=get_act_idx(harmless, deephub_layer, layer_num)[:, pos, :].mean(dim=0)refusal_dir=harmful_mean_act-harmless_mean_actrefusal_dir=refusal_dir/refusal_dir.norm()activation_refusals[layer].append(refusal_dir)selected_layers= ["resid_pre"]activation_scored=sorted([activation_refusals[layer][l-1]forlinrange(1, model.cfg.n_layers)forlayerinselected_layers],key=lambdax: abs(x.mean()),reverse=True,)

最后一步包需要评估我们计算的拒绝方向。将在推理期间对每个残差流和每个块应用拒绝方向。在下面的代码片段中,是得四个测试有害指令和20个块(或层)的输出。

 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]] =tokensforiinrange(max_tokens_generated):withmodel.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_tokensreturntokenizer.batch_decode(all_tokens[:, tokens.shape[1] :], skip_special_tokens=True)defget_generations(deephub_model: HookedTransformer,tokenizer: AutoTokenizer,instructions: List[str],fwd_hooks=[],max_tokens_generated: int=64,batch_size: int=4,) ->List[str]:generations= []foriintqdm(range(0, len(instructions), batch_size)):tokens=tokenize_instructions(tokenizer, instructions=instructions[i : i+batch_size])generation=_generate_with_hooks(deephub_model,tokenizer,tokens,max_tokens_generated=max_tokens_generated,fwd_hooks=fwd_hooks,)generations.extend(generation)returngenerations# Inference-time intervention hookdefdirection_ablation_hook(activation: Float[Tensor, "... d_act"],deephub_hook: HookPoint,direction: Float[Tensor, "d_act"],):ifactivation.device!=direction.device:direction=direction.to(activation.device)proj= (einops.einsum(activation, direction.view(-1, 1), "... d_act, d_act single -> ... single")*direction)returnactivation-proj# Testing baselineN_INST_TEST=4baseline_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 directionsevals= []forrefusal_dirintqdm(activation_scored[:EVAL_N]):deephub_hook_fn=functools.partial(direction_ablation_hook, direction=refusal_dir)fwd_hooks= [(utils.get_act_name(act_name, layer), deephub_hook_fn)forlayerinlist(range(model.cfg.n_layers))foract_nameinactivation_layers]intervention_generations=get_generations(model, tokenizer, harmful_inst_test[:N_INST_TEST], fwd_hooks=fwd_hooks)evals.append(intervention_generations)

将所有的generations存储在eval列表中。现在可以打印它们并手动选择为每个指令提供未经审查的响应的层(块)。

如果你找不到满足这些要求的层,可能需要测试前面的selected_layers列表中的其他残差流、指令、附加块等,这个可能和模型架构有关系需要仔细的比对。

下面代码自动排除包含“我不能”和“我不能”的回复,这样就可以过滤掉不想要的回答。

 # Print generations for human evaluationblacklist = ["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为这四个指令提供了未经审查的答案。这是我们将选择的拒绝方向。下面就是实现权值正交化来修改权值,防止模型创建具有该方向的输出。可以通过打印补全来验证模型是否成功地不受审查。

 defget_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)returnmatrix-proj# Select the layer with the highest potential refusal directionLAYER_CANDIDATE=9refusal_dir=activation_scored[LAYER_CANDIDATE]# Orthogonalize the model's weightsifrefusal_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)forblockintqdm(model.blocks):ifrefusal_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 modelorthogonalized_generations=get_generations(model, tokenizer, harmful_inst_test[:N_INST_TEST], fwd_hooks=[])# Print generationsforiinrange(N_INST_TEST):iflen(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")

这样我们就修改完成了这个模型。将其转换回Hugging Face 格式,也可以上传到HF hub上

 # Convert model back to HF safetensorshf_model=AutoModelForCausalLM.from_pretrained(MODEL_TYPE, torch_dtype=torch.bfloat16)lm_model=hf_model.modelstate_dict=model.state_dict()lm_model.embed_tokens.weight=torch.nn.Parameter(state_dict["embed.W_E"].cpu())forlinrange(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")

DPO微调

在Open LLM排行榜和Nous的基准测试上评估了上面的删除模型和源模型。结果如下:

源模型明显优于 Llama 3 8B Instruct。但是我们修改的模型降低了模型的质量。

为了解决这个问题,我们可以来对他进行微调,但是Llama 3 8B Instruct在监督微调方面非常脆弱。额外的SFT可能会破坏模型的性能。

所以我们这里选择偏好对齐。因为他是相当轻量的,不应该使我们的模型损失性能。DPO是一个很好的候选,因为它易于使用和良好的跟踪记录。这里我使用了LazyAxolotl和mlabonne/orpo-dpo-mix-40k数据集。下面是我使用的配置:

 base_model: mlabonne/Daredevil-8B-abliteratedmodel_type: LlamaForCausalLMtokenizer_type: AutoTokenizerload_in_8bit: falseload_in_4bit: truestrict: falsesave_safetensors: truerl: dpochat_template: chatmldatasets:- path: mlabonne/orpo-dpo-mix-40ksplit: traintype: chatml.inteldataset_prepared_path:val_set_size: 0.0output_dir: ./outadapter: qloralora_model_dir:sequence_len: 2048sample_packing: falsepad_to_sequence_len: falselora_r: 64lora_alpha: 32lora_dropout: 0.05lora_target_linear: truelora_fan_in_fan_out:wandb_project: axolotlwandb_entity:wandb_watch:wandb_name:wandb_log_model:gradient_accumulation_steps: 8micro_batch_size: 1num_epochs: 1optimizer: paged_adamw_8bitlr_scheduler: cosinelearning_rate: 5e-6train_on_inputs: falsegroup_by_length: falsebf16: autofp16:tf32:gradient_checkpointing: trueearly_stopping_patience:resume_from_checkpoint:local_rank:logging_steps: 1xformers_attention:flash_attention: truewarmup_steps: 100evals_per_epoch: 0eval_table_size:eval_table_max_new_tokens: 128saves_per_epoch: 1debug:deepspeed: deepspeed_configs/zero2.jsonweight_decay: 0.0special_tokens:pad_token: <|end_of_text|>

用6个A6000 和DeepSpeed ZeRO-2来训练它。这次训练耗时约6小时45分钟。以下是我从W&B得到的训练曲线:

我们来看看微调模型的表现:

我们可以看到,这种额外的训练使我们能够恢复由于“消字”而导致的大部分性能下降。模型没有改进的一个领域是GSM8K,这是肯定的,因为它是一个数学数据集,跟我们的研究方向无关。

总结

在这篇文章中,我们介绍了“消除”的概念。该技术利用模型在无害和有害提示上的激活来计算拒绝方向。然后,它使用这个方向来修改模型的权重,并确保我们不输出拒绝信息。这项技术也证明了安全微调的脆弱性,并引发了伦理问题。

对模型进行了消除后会降低了模型的性能。我们则可以使用DPO修复了它,这样就可以得到一个完整的并且效果十分不错的模型。

但是“消除”并不应局限于去除对齐,应该被视为一种无需再训练的微调技术。因为它可以创造性地应用于其他目标,比如FailSpy的MopeyMule(它采用了忧郁的对话风格)。

最后github库

https://avoid.overfit.cn/post/e828cf84358d42f6b4690d4c1c5669d8

作者:Maxime Labonne

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/26939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

化学品危险性分类鉴定报告 危化品危险性分类

一、化学品危险性分类报告&#xff1a; 按照国务院令 第591号 《危险化学品安全管理条例》、原十部委公告 2015年 第5号 《危险化学品目录&#xff08;2015版&#xff09;》、原安监总局令 第60号《化学品物理危险性鉴定与分类管理办法》和原安监总局令 第53号《危险化学品登记…

IBM Spectrum LSF Process Manager 在共享分布式计算环境中运行和管理业务关键工作流程

亮点 ● 快速创建复杂的分布式工作流 ● 开发可重复的最佳实践 ● 自信地运行关键工作流程 ● 提高流程可靠性 IBM Spectrum LSF Process Manager 使您能够设计和自动化计算或分析流程&#xff0c; 捕获和保护可重复的最佳实践。 使用直观的图形界面&#xff0c;您可以轻松记录…

【漏洞复现】飞企互联-FE企业运营管理平台 treeXml.jsp SQL注入漏洞

0x01 产品简介 飞企互联-FE企业运营管理平台是一个基于云计算、智能化、大数据、物联网、移动互联网等技术支撑的云工作台。这个平台可以连接人、链接端、联通内外&#xff0c;支持企业B2B、C2B与020等核心需求&#xff0c;为不同行业客户的互联网转型提供支持。其特色在于提供…

【十大排序算法】基数排序

数字犹如无数繁星&#xff0c;基数排序如晨曦的指引&#xff0c;将混沌序列织就成和谐的序曲。 文章目录 一、基数排序二、发展历史三、处理流程四、算法实现五、算法特性六、小结推荐阅读 一、基数排序 基数排序是一种非比较性的排序算法&#xff0c;它根据元素的位数来对元…

极限网关助力好未来 Elasticsearch 容器化升级

极限网关在好未来的最佳实践案例&#xff0c;轻松扛住日增百 TB 数据的流量&#xff0c;助力 ES 从物理机到云原生架构的改造&#xff0c;实现了流控、请求分析、安全管理、无缝迁移等场景。一次完美的客户体验~ 背景 物理机架构时代 2022 年&#xff0c;好未来整个日志 Elas…

教学辅助系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;教师管理&#xff0c;作业管理&#xff0c;学生管理&#xff0c;管理员管理&#xff0c;作业提交管理&#xff0c;教学视频管理 教室账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0…

React+TS前台项目实战(九)-- 全局常用组件弹窗Dialog封装

文章目录 前言Dialog公共弹窗组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局公共弹窗Dialog组件封装&#xff0c;将用到上篇封装的模态框Modal组件。有时在前台项目中&#xff0c;偶尔要用到一两个常用的组件&#xff0c;如 弹窗&#x…

HTTP 概述

HTTP 概述 HTTP 是一种用于获取资源&#xff08;如 HTML 文档&#xff09;的协议。 它是 Web 上任何数据交换的基础&#xff0c;它是一种客户端-服务器协议&#xff0c;这意味着请求由接收方&#xff08;通常是 Web 浏览器&#xff09;发起。 一个完整的文档是从获取的不同子文…

2024全国大学生信息安全竞赛(ciscn)半决赛东北赛区Pwn题解

前言 今年Ciscn华东北赛区半决赛的时间比较晚&#xff0c;找东北赛区的师傅要了一份半决赛Pwn题。 听说好像有5个Pwn题&#xff0c;但是只拿到了4个。如果有师傅有剩下那一个欢迎私信我。 拿到手的4个除了最后一个vmJS&#xff0c;还是挺简单的。都是格式化字符串、栈溢出和…

构建 LLM 应用为什么需要文本加载器,langchain 中如何使用文本加载器?

构建 LLM 应用为什么需要文本加载器&#xff0c;langchain 中如何使用文本加载器&#xff1f; 上一篇文章中 [使用langchain搭建本地知识库系统(新) 我们构建一个 RAG 的本地应用&#xff0c;我们使用到了网页的文本加载器用来动态获取网页的数据。 在不同的应用场景中需要使…

QQ 邮箱绑定校园邮箱失败但 Coremail 论客绑定成功

目录 1 查看本校学生邮件系统官网 2 QQ 邮箱绑定失败 3 Coremail 论客绑定成功 前言&#xff1a;个人觉得每次查看校园邮箱都要打开电脑很不方便&#xff0c;遂决定绑定到 QQ 邮箱 APP 上。 1 查看本校学生邮件系统官网 仅针对我们学校&#xff0c;登录页面给出了邮件服…

MYSQL 索引下推 45讲

刘老师群里,看到一位小友 问<MYSQL 45讲>林晓斌的回答 大意是一个组合索引 (a,b,c) 条件 a > 5 and a <10 and b123, 这样的情况下是如何? 林老师给的回答是 A>5 ,然后下推B123 小友 问 "为什么不是先 进行范围查询,然后在索引下推 b123?" 然后就…

热门开源大模型项目推荐

一&#xff1a;开源大模型热门项目推荐 NNI&#xff1a;由微软发布的开源AutoML工具包&#xff0c;支持神经网络超参数调整。最新版本对机器学习生命周期的各个环节做了全面支持&#xff0c;包括特征工程、神经网络架构搜索(NAS)、超参调优和模型压缩。适用于各种机器学习项目&…

C++240613

自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面 要求&#xff1a;每行代码都有注释 #include "my_widget.h"My_Widget::My_Widget(QWidget *parent): QWidget(parent) {//设置窗口的标题this->setWindowTitle("真爱生命&#xff0c;远离赌博&…

2024大交通场景空间策展洞察报告

来源&#xff1a;邻汇吧&万一商管 近期历史回顾&#xff1a; 2024国内工商业储能市场研究报告.pdf 2023幸福企业白皮书.pdf 2024年欧亚地区移动经济报告.pdf 内容供应链变革 2023人工智能与首席营销官&#xff08;CMO&#xff09; AI科技对PC产业的影响.pdf 金融业数据应用…

智能合约漏洞类型

Are We There Yet? Unraveling the State-of-the-Art Smart Contract Fuzzers | Proceedings of the IEEE/ACM 46th International Conference on Software Engineering

Java求职季 必备知识脑图 收藏起来 !!!

Java初中级知识脑图 面试超实用 1.Git 下载链接 导图下载地址 &#xff1a; https://mm.edrawsoft.cn/mobile-share/index.html?uuid31d00742157057-src&share_type1 2.JUC 下载链接 https://mm.edrawsoft.cn/mobile-share/index.html?uuid6c0be457444921-src&s…

计算机网络 —— 应用层(DNS域名系统)

计算机网络 —— 应用层&#xff08;DNS域名系统&#xff09; 什么是DNS域名的层次结构域名分类 域名服务器的分类域名解析方式递归查询&#xff08;Recursive Query&#xff09;迭代查询&#xff08;Iterative Query&#xff09;域名的高速缓存 我们今天来看DNS域名系统 什么…

批量文件重命名技巧:轻松替换删除文件夹名中的字母,实现高效文件管理新境界

在数字化时代&#xff0c;我们每天都会面对大量的文件和文件夹。无论是工作文档、学习资料还是个人收藏&#xff0c;文件命名的规范性都显得尤为重要。然而&#xff0c;手动一个一个去修改文件名&#xff0c;不仅耗时耗力&#xff0c;还容易出错。那么&#xff0c;有没有一种方…

SAP ABAP 之面向对象OO

文章目录 前言一、类的理解二、如何创建ABAP类 a.类的定义与构成 b.类的访问区域 c.特殊方法 d.类的继承 三、类中参数的使用 a.IMPORTING / EXPORTING b.CHANGING c.RETURNING d.EX…