当前位置: 首页 > news >正文

使用‘消除’技术绕过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

相关文章:

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

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

解决使用elmessage 没有样式的问题

错误情况 这里使用了一个消息提示&#xff0c;但是没有出现正确的样式&#xff0c; 错误原因和解决方法 出现这种情况是因为&#xff0c;在全局使用了按需导入&#xff0c;而又在局部组件中导入了ElMessage组件&#xff0c;我们只需要将局部组件的import删除就可以了 import…...

pxe批量部署linux介绍

1、PXE批量部署的作用及必要性&#xff1a; 1&#xff09;智能实现操作系统的批量安装&#xff08;无人值守安装&#xff09;2&#xff09;减少管理员工作&#xff0c;提高工作效率3&#xff09;可以定制操作系统的安装流程a.标准流程定制(ks.cfg)b.自定义流程定制(ks.cfg(%pos…...

RAG 实践-Ollama+AnythingLLM 搭建本地知识库

什么是 RAG RAG&#xff0c;即检索增强生成&#xff08;Retrieval-Augmented Generation&#xff09;&#xff0c;是一种先进的自然语言处理技术架构&#xff0c;它旨在克服传统大型语言模型&#xff08;LLMs&#xff09;在处理开放域问题时的信息容量限制和时效性不足。RAG的…...

【超详细】使用RedissonClient实现Redis分布式锁

使用RedissonClient实现Redis分布式锁是一个非常简洁和高效的方式。Redisson是一个基于Redis的Java客户端&#xff0c;它提供了许多高级功能&#xff0c;包括分布式锁、分布式集合、分布式映射等&#xff0c;简化了分布式系统中的并发控制。 添加依赖 首先&#xff0c;你需要…...

CC攻击的有效应对方案

随着互联网的发展&#xff0c;网络安全问题愈发突出。CC攻击&#xff08;Challenge Collapsar Attack&#xff09;&#xff0c;一种针对Web应用程序的分布式拒绝服务&#xff08;DDoS&#xff09;攻击方式&#xff0c;已经成为许多网络管理员和网站拥有者不得不面对的重大挑战。…...

自动驾驶基础一车辆模型

模型概述&#xff1a; 自行车动力学模型通常用于研究自行车在骑行过程中的行为&#xff0c;如稳定性、操控性和速度等。模型可以基于不同的简化假设和复杂度&#xff0c;从简单的二维模型到复杂的三维模型&#xff0c;甚至包括骑行者的动态。力学方程&#xff1a; 基础物理学方…...

机器学习:数据分布的漂移问题及应对方案

首先&#xff0c;让我们从一位高管告诉我的一个故事开始&#xff0c;很多读者可能对此感同身受。 大约两年前&#xff0c;他的公司聘请了一家咨询公司开发一个机器学习模型&#xff0c;帮助他们预测下周每种食品杂货需要多少&#xff0c;以便他们可以相应地补货。这家咨询公司…...

公链常用的共识算法

1. 工作量证明&#xff08;Proof of Work, PoW&#xff09; 工作原理&#xff1a;要求节点&#xff08;矿工&#xff09;解决一个数学难题&#xff0c;这个过程称为挖矿。第一个解决难题的矿工将有权添加一个新的区块到区块链上&#xff0c;并获得一定数量的加密货币作为奖励。…...

详解 Flink Table API 和 Flink SQL 之函数

一、系统内置函数 1. 比较函数 API函数表达式示例Table API&#xff0c;>&#xff0c;<&#xff0c;!&#xff0c;>&#xff0c;<id1001&#xff0c;age>18SQL&#xff0c;>&#xff0c;<&#xff0c;!&#xff0c;>&#xff0c;<id‘1001’&…...

rsa加签验签C#和js以及java互通

js实现rsa加签验签 https://github.com/kjur/jsrsasign 11.1.0版本 解压选择需要的版本&#xff0c;这里选择all版本了 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>JS RSA加签验签</title&g…...

C语言中数组和指针的关系

在C语言中&#xff0c;数组和指针之间存在着密切的关系&#xff0c;尽管它们在概念上是不同的。以下是关于C语言中数组和指针关系的一些要点&#xff1a; 数组名作为指针&#xff1a; 在大多数情况下&#xff0c;数组名在表达式中会被当作指向其第一个元素的指针。例如&#x…...

idea 新建一个 JSP(JavaServer Pages)项目

环境设置&#xff1a; 确保你的开发环境中已经安装了 Java 开发工具包&#xff08;JDK&#xff09;和一个 Java Web 开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;比如 Eclipse、IntelliJ IDEA 或者 NetBeans。你还需要一个 Web 服务器&#xff0c;比如 Apache T…...

【名词解释】Unity中的表格布局组件及其使用示例

Unity中的表格布局组件通常指的是GridLayoutGroup&#xff0c;这是一个在Unity的UI系统中用来布局子对象的组件。它可以帮助开发者将UI元素按照网格的形式进行排列&#xff0c;非常适合创建表格、网格视图等布局。 名词解释&#xff1a; GridLayoutGroup&#xff1a;Unity UI…...

判断当前设备为移动端自适应 平板和pc端为375移动端样式

在libs的setRem.js中&#xff1a; let html document.querySelector("html"); function setRem() {let ui_w 375;let cl_w document.documentElement.clientWidth || document.body.clientWidth;cl_w > 750 ? cl_w 375 : "";html.style.fontSize …...

Science Advances|用于胃部pH监测和早期胃漏检测的生物可吸收无线无源柔性传感器(健康监测/柔性传感/柔性电子)

2024年4月19日,美国西北大学 John A. Rogers和中国科学技术大学吕頔(Di Lu)团队,在《Science Advances》上发布了一篇题为“Bioresorbable, wireless, passive sensors for continuous pH measurements and early detection of gastric leakage”的论文。论文内容如下: 一、…...

C# 使用 webview2 嵌入网页

需求&#xff1a;C#客户端程序, 窗口里嵌入一个web网页&#xff0c;可通过URL跳转的那种。并且&#xff0c;需要将登录的身份验证信息&#xff08;token&#xff09;设置到请求头里。 核心代码如下&#xff1a; // 打开按钮的点击事件 private void openBtn_Click(object sen…...

公司面试题总结(五)

25.谈一谈箭头函数与普通函数的区别&#xff0c;箭头函数主要解决什么问题&#xff1f; 箭头函数与普通函数的区别&#xff1a; ⚫ 语法简洁性&#xff1a; ◼ 箭头函数使用>符号定义&#xff0c;省略了 function 关键字&#xff0c;使得语法更为紧凑。 ◼ 对于单行函…...

Flutter笔记:关于WebView插件的用法(上)

Flutter笔记 关于WebView插件的用法&#xff08;上&#xff09; - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:htt…...

计算机毕业设计Python+Django农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop Hive

课题研究的意义&#xff0c;国内外研究现状、水平和发展趋势 研究意义21世纪是一个信息爆炸的时代&#xff0c;人们在日常生活中可接触到的信息量非常之巨大。推荐系统逐步发展&#xff0c;其中又以个性化推荐系统最为瞩目。个性化推荐系统的核心在于个性化推荐算法&#xff0c…...

phpcms仿蚁乐购淘宝客网站模板

phpcms仿蚁乐购网站模板&#xff0c;淘宝客行业模板免费下载&#xff0c;该模板网站很容易吸引访客点击&#xff0c;提升ip流量和pv是非常有利的。本套模板采用现在非常流行的全屏自适应布局设计&#xff0c;且栏目列表以简洁&#xff0c;非常时尚大气。页面根据分辨率大小而自…...

leetcode695 岛屿的最大面积

题目 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0&#xff08;代表水&#xff09;包围着。 岛屿的面积是岛上值…...

小程序无法调用服务端问题排查

1、问题描述 突然有一天线上的小程序不能登录&#xff0c;经查小程序无法调用。经查无法小程序页面无法调用后台服务。 2、排查过程 由于无法登录小程序发布服务器&#xff0c;无法测试小程序前端服务器到服务端网络&#xff0c;并且小程序无法看到日志。所以就得从服务端和网…...

Linux:多线程的操作

多线程操作 进程与线程线程的创建 create_pthread创建线程池给线程传入对象的指针 线程等待 pthread_join退出线程 pthread_exit线程等待参数 retval 与 线程退出参数 retval 线程中断 pthread_cancel获取线程编号 pthread_self线程分离 pthread_detach 进程与线程 进程是资源…...

kunpeng的aarch64架构cpu、openeuler系统、昇腾服务器适配文档转换功能(doc转docx、ppt转pptx)

一、安装flatpak sudo yum install flatpak flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo二、安装libreoffice flatpak install flathub org.libreoffice.LibreOffice三、使用 对于使用 flatpak 安装的 LibreOffice,不需要手…...

unity 打包PC安装包中常见文件的功能

目录 前言 一、打包好的文件 二、常用文件 1.文件夹XXX_Data 2.文件夹MonoBleedingEdge 3.文件夹XXX_Data内部 三、文件的应用 1.如果你替换了一个图片 2.如果你新增了或减少了图片和资源 3.场景中有变动 4.resources代码加载的资源改了 5.如果你代码替换了 四、作…...

【Ardiuno】实验使用ESP32单片机实现高级web服务器暂时动态图表功能(图文)

接下来&#xff0c;我们继续实验示例代码中的Wifi“高级web服务器”&#xff0c;配置相关的无线密码后&#xff0c;开始实验 #include <WiFi.h> #include <WiFiClient.h> #include <WebServer.h> #include <ESPmDNS.h>const char *ssid "XIAOFE…...

深入浅出服务网格(Service Mesh):现代微服务架构的护航者

什么是服务网格&#xff1f; 服务网格是一种专用于处理微服务间通信的基础设施层&#xff0c;通常以轻量级代理&#xff08;sidecar&#xff09;的形式部署在每个服务实例旁边。它主要负责以下几项任务&#xff1a; 服务发现&#xff1a;自动检测和注册服务实例&#xff0c;使…...

node调试

vscode安装插件&#xff1a;JavaScript Debugger (Nightly) 点击后生成一个launch.json文件 打断点&#xff0c;并发送一个请求来执行代码到断点处 按右上的向下箭头&#xff0c;进入源码&#xff0c;进行查看&#xff0c;左边查看变量等值...

docker拉取镜像失败超时的解决方法,docker配置国内镜像源

更换国内源 创建或修改 /etc/docker/daemon.json 文件 安装docker后一般只有 /etc/docker 这个目录 下面并没有 daemon.json 文件 我们直接创建 &#xff1a; vim /etc/docker/daemon.json {"registry-mirrors" : ["https://registry.docker-cn.com"…...

做网站设计需要办理icp/东莞网络营销全网推广

代码https://resources.oreilly.com/examples/9780596005559/ 移动模式是制造智能行为幻觉的简单方式。 实现移动模式的标准做法是选取想要的模式&#xff0c;再将控制数据填入某个数组或多个数组。控制数据由特定的移动指令组成&#xff0c;比如向前移动再转弯&#xff0c;借…...

石湾做网站/百度知道答题赚钱

OSSIM安装注意事项 1.如何选择OSSIM版本 SIEM (安全信息和事件管理)是软件和服务的组合,是安全信息管理和安全事件管理的融合体。SIEM可以管理企业IT资源产生的安全信息(包括日志、告警等)进行统一的实时监控误操作行为进行监控、审计分析、调查取证、出具各种报表报告。OSS…...

网站建设7个基本流程/淘宝搜索指数

综述:文本分析在市场营销研究中的应用文本大数据分析在经济学和金融学中的应用&#xff1a;一个文献综述倒计时4天&#xff5c;Python&Stata数据分析课寒假工作坊大数据时代到来&#xff0c;网络数据正成为潜在宝藏&#xff0c;大量商业信息、社会信息以文本等非结构化、异…...

阿里云wordpress搭建网站/淘宝运营培训班哪里有

对于一个待测试的对象&#xff0c;我们通常通过以下几个方面来进行测试&#xff1a;功能测试、可靠性测试、易用性测试、效率、可维护性、可移植性、安全性测试、界面测试等。 本文将其分成两个方面来看&#xff1a; &#xff08;1&#xff09;站在测试人员的技术测试角度&…...

怎么看网站有没有做推广/厨师培训学校

鐵鍋燉腯鱻 项目&#xff1a;小鱼记账 团队成员项目燃尽图冲刺情况描述站立式会议照片各成员情况团队成员 学号姓名git地址博客地址031602240许郁杨 &#xff08;组长&#xff09;https://github.com/EventideXhttp://www.cnblogs.com/S031602240/181600333杨心逸https://githu…...

安平县护栏网站建设/上海外贸seo

1.功能描述&#xff1a;支持对图片中的手写中文、手写数字进行检测和识别&#xff0c;针对不规则的手写字体进行专项优化&#xff0c;识别准确率可达90%以上2.平台接入具体接入方式比较简单&#xff0c;可以参考我的另一个帖子&#xff0c;这里就不重复了&#xff1a;http://ai…...