LLM 模型融合实践指南:低成本构建高性能语言模型

编者按:随着大语言模型技术的快速发展,模型融合成为一种低成本但高性能的模型构建新途径。本文作者 Maxime Labonne 利用 mergekit 库探索了四种模型融合方法:SLERP、TIES、DARE和passthrough。通过配置示例和案例分析,作者详细阐释了这些算法的原理及实践操作。

作者的核心观点是:相比训练全新模型,融合现有模型可以以更低计算成本获取类似或更优异的效果。

文章通过模型融合生成了性能优异的 Marcoro14-7B-slerp 。在 Open LLM Leaderboard 和 NousResearch 两个基准测试上,它都是同参数量模型中的佼佼者。案例验证了作者主张的模型融合存在的高性价比。当然模型融合也存在一定问题,如训练数据污染和可能在各种评测排行榜的分数偏高。本文提供了模型融合技术与工程实践的详尽指南,对AI实践者具有重要参考价值。

作者 | Maxime Labonne

编译 | 岳扬

Image by author

模型融合(Model merging)是一种将两个或更多个大语言模型(LLM)合并为一个模型的技术。这是一种相对较新的实验性方法,可以以较低成本(无需 GPU)创建新模型。 令人惊讶的是,这种技术的效果还比较出奇,使用模型融合技术在 Open LLM Leaderboard[1]上产生了许多最先进的模型。

在本教程中,我们将使用 mergekit [2]库来实现这一技术。更具体地说,我们将回顾四种模型融合方法,并提供相关的配置示例。然后,我们将使用 mergekit 创建一个模型:Marcoro14–7B-slerp[3],该模型已成为 Open LLM Leaderboard(02/01/24)上表现最佳的模型。

相关代码已上传至 GitHub[4] 和 Notebook[5]。个人建议使用 LazyMergekit[6] 项目,来轻松运行 mergekit。

特别感谢 mergekit 库的作者 Charles Goddard[7] 审阅本文。

Image by author

01 🤝 融合算法

在本节,我们将重点介绍 mergekit 库目前实现的四种模型融合方法。请注意,还有其他方法,比如 linear [8]和 Task Arithmetic [9]。如果你对模型融合的相关论文感兴趣,我推荐阅读Hugging Face上的这本优秀论文集[10]。

1.1 SLERP

Spherical Linear Interpolation(SLERP)是一种用于在两个向量之间进行平稳和连贯地插值的方法。这种方法能够保持恒定的变化速率,并保留向量所在球面空间的几何特性。

与使用传统的线性插值方法相比,SLERP 更受青睐的原因有几个。例如,在高维空间中,线性插值(linear interpolation)可能导致插值向量的大小(幅度)减小(即权重的规模减小)。此外,权重方向的变化往往比大小(幅度)的变化代表的信息更有意义(如特征学习(Feature Learning)和表征(Representation))。

SLERP 是通过以下步骤实现的:

  1. 对输入的向量进行归一化处理,使它们的长度(magnitude)变为单位长度(长度为1)。这一步骤的目的是确保这些向量表示的是方向,而不是大小。
  2. 使用点积计算这些向量之间的角度。
  3. 如果这些向量几乎平行,则默认使用线性插值以提高效率。如果输入的两个向量夹角较大,SLERP 将根据插值因子 t (插值因子 t 是一个介于 0 到 1 之间的值,用于指定插值的程度。t=0 表示完全使用第一个向量,t=1 表示完全使用第二个向量,而在 0 到 1 之间的值表示两个向量的混合程度。 )和向量之间的夹角计算比例因子(Scale factor)。
  4. 这些因子用于给原始向量加权,然后求和来获得插值向量。

SLERP 目前是最流行的模型融合方法,但它仅限于一次合并两个模型。不过,仍然可以通过分层融合多个模型,就像在 Mistral-7B-Merge-14-v0.1[11] 中所示。

配置示例:

slices:- sources:- model: OpenPipe/mistral-ft-optimized-1218layer_range: [0, 32]- model: mlabonne/NeuralHermes-2.5-Mistral-7Blayer_range: [0, 32]
merge_method: slerp
base_model: OpenPipe/mistral-ft-optimized-1218
parameters:t:- filter: self_attnvalue: [0, 0.5, 0.3, 0.7, 1]- filter: mlpvalue: [1, 0.5, 0.7, 0.3, 0]- value: 0.5
dtype: bfloat16

这是一种经典的 SLERP 配置,SLERP 被应用于模型的每一层,以完成整体的模型融合。请注意,我们为插值因子 t 输入了一系列梯度值(gradient of values)。自注意力层和 MLP 层的参数将使用 OpenPipe/mistral-ft-optimized-1218[12] 和 mlabonne/NeuralHermes-2.5-Mistral-7B[13] 的不同组合。

可以在 Hugging Face Hub 上找到最终训练完成的模型,位于 mlabonne/NeuralPipe-7B-slerp[14]。

1.2 TIES

TIES-Merging 由 Yadav 等人在这篇论文[15]中引入,TIES-Merging 旨在将多个特定任务模型高效地合并为一个多任务模型。它解决了模型融合中的两大难题:

  • 模型参数的冗余:它能够识别并消除特定任务模型中的冗余参数。具体做法是在模型微调(fine-tuning)的过程中,关注模型参数发生的变化,对微调过程中发生的变化进行排序,并选择那些对模型性能影响最显著的前 k% 的变化,并忽略那些在微调中变化较小或对性能影响较小的部分。
  • 模型参数的符号之间存在分歧:当不同模型对同一参数提出相反的调整建议时,就会产生冲突。TIES-Merging 通过创建一个统一的符号向量来解决这些冲突,该向量表示所有模型中变化方向的最显著方向。

TIES-Merging 分为以下三个步骤:

  • Trim(修剪) :只保留一部分最重要的参数(密度参数(density parameter)),并将其余参数重置为零,从而减少特定任务模型中的冗余参数。
  • Elect Sign(确定符号) :通过确定模型中哪些方向上的变化(正向或负向)是最为显著或最主导的,创建一个统一的符号向量,以解决不同模型之间的符号冲突。
  • Disjoint Merge:在合并过程中,仅考虑那些与先前创建的统一符号向量一致的参数值,并计算这些值的平均值。在计算平均值时,不考虑原始参数值为零的情况。

与 SLERP 不同,TIES 可以一次性合并多个模型。

配置示例:

models:- model: mistralai/Mistral-7B-v0.1# no parameters necessary for base model- model: OpenPipe/mistral-ft-optimized-1218parameters:density: 0.5weight: 0.5- model: mlabonne/NeuralHermes-2.5-Mistral-7Bparameters:density: 0.5weight: 0.3
merge_method: ties
base_model: mistralai/Mistral-7B-v0.1
parameters:normalize: true
dtype: float16

在此配置下,我们使用 Mistral-7B 作为基础模型来计算 delta 权重。我们融合了两个模型:mistral-ft-optimized-1218(50%)[12]和 NeuralHermes-2.5-Mistral-7B(30%)[13],并进行了归一化处理。这里的“density”参数意味着我们只保留了每个模型 50%的参数(另一半来自基础模型)。

请注意,在配置中权重之和不等于 1,但 normalize: true 参数会自动在内部将其归一化。 此配置的灵感来自 OpenHermes-2.5-neural-chat-7b-v3-1-7B[16] 这个模型的作者提供的参数。

你可以在 Hugging Face Hub 上的 mlabonne/NeuralPipe-7B-ties[17] 找到最终训练完成的模型。

1.3 DARE

DARE[18] 由 Yu 等人(2023 年)提出,使用了与 TIES 类似的方法,但有两个主要区别:

  • Pruning: DARE 随机将微调后的权重重置为原始值(基础模型的权重)。
  • Rescaling: DARE 重新调整权重,以保持模型输出的期望值大致不变。它将两个(或更多)模型的重调整后的权重与基础模型的权重相加,并使用了一个比例因子。

Mergekit 对这种方法的实现有两种:有 TIES 的确定符号步骤(dare_ties)或没有 TIES 的确定符号步骤(dare_linear)。

配置示例:

models:- model: mistralai/Mistral-7B-v0.1# No parameters necessary for base model- model: samir-fama/SamirGPT-v1parameters:density: 0.53weight: 0.4- model: abacusai/Slerp-CM-mist-dpoparameters:density: 0.53weight: 0.3- model: EmbeddedLLM/Mistral-7B-Merge-14-v0.2parameters:density: 0.53weight: 0.3
merge_method: dare_ties
base_model: mistralai/Mistral-7B-v0.1
parameters:int8_mask: true
dtype: bfloat16

在这个配置示例中,我们使用 dare_ties 合并了基于 Mistral-7B 的三个不同模型。这次,我选择的权重总和为 1(总和应在 0.9 和 1.1 之间)。density 参数略高于论文中建议的值(<0.5),但看起来它能持续提供更好的结果(参见此讨论[19])。

你可以在 Hugging Face Hub 的 mlabonne/Daredevil-7B[20] 上找到它。它也是本文中最好的合并模型,甚至优于 Marcoro14-7B-slerp。

1.4 Passthrough

Passthrough 方法与前几种方法有很大不同。通过连接来自不同 LLMs 的模型层,这种方法可以生成具有奇怪参数数量的模型(例如,使用两个 7B 参数模型可以生成 9B 模型)。 这些模型通常被称为 "Frankenmerges "或 “Frankenstein 模型”。

这种技术极具实验性,但能够成功地创建一些令人印象深刻的模型,比如使用两个 Llama 2 70B 模型融合而成的 goliath-120b。最近发布的 SOLAR-10.7B-v1.0 也使用了同样的思想,在他们的论文中这种技术称为"depth-up scaling"。

配置示例:

slices:- sources:- model: OpenPipe/mistral-ft-optimized-1218layer_range: [0, 32]- sources:- model: mlabonne/NeuralHermes-2.5-Mistral-7Blayer_range: [24, 32]
merge_method: passthrough
dtype: bfloat16

由此产生的 frankenmerge 模型将包含第一个模型的全部 32 层和第二个模型的 8 个附加层。这将创建一个总共有 40 层和 8.99B 参数的 frankenmerge。此配置的灵感来自于 GML-Mistral-merged-v1[21]。

您可以在 Hugging Face Hub 上的 mlabonne/NeuralPipe-9B-merged [22]找到最终模型。

02 💻 融合我们自己的模型

在本节中,我们将使用 mergekit 库加载一个模型融合配置,运行它并将生成的结果模型上传到 Hugging Face Hub。

首先,我们直接通过源代码安装 mergekit,步骤如下:

!git clone https://github.com/cg123/mergekit.git
!cd mergekit && pip install -q -e .

在下面的代码块中,我们将以 YAML 格式加载模型融合配置。还在此指定了完成模型融合后模型的名称,以备将来使用。您可以在此复制/粘贴上一节中的任何配置。

这次,我们将使用两个不同的模型: Marcoroni-7B-v3[23] 和 Mistral-7B-Merge-14-v0.1[24] 并用 SLERP 方法进行模型融合。然后将配置保存为 yaml 文件,以便用作模型融合命令的输入。

import yamlMODEL_NAME = "Marcoro14-7B-slerp"
yaml_config = """
slices:- sources:- model: AIDC-ai-business/Marcoroni-7B-v3layer_range: [0, 32]- model: EmbeddedLLM/Mistral-7B-Merge-14-v0.1layer_range: [0, 32]
merge_method: slerp
base_model: AIDC-ai-business/Marcoroni-7B-v3
parameters:t:- filter: self_attnvalue: [0, 0.5, 0.3, 0.7, 1]- filter: mlpvalue: [1, 0.5, 0.7, 0.3, 0]- value: 0.5
dtype: bfloat16"""# Save config as yaml file
with open('config.yaml', 'w', encoding="utf-8") as f:f.write(yaml_config)

我们会使用以下参数运行模型融合命令:

  • –copy-tokenizer 用于从基础模型复制分词器
  • –allow-crimes 和 --out-shard-size 可用于将模型划分为较小的分片(shards),可在内存较小的 CPU 上进行计算
  • –lazy-unpickle 用于启用实验性的lazy unpickler(译者注:“lazy unpickler” 指的是一种实验性的、能够以一种惰性或延迟加载的方式执行反序列化操作的机制。),以降低内存使用率

此外,某些模型可能还需要 --trust_remote_code 参数(Mistral-7B 不需要)。

该命令将下载模型融合配置中列出的所有模型的权重,并运行所选的模型融合方法(应该需要约 10 分钟)。

# Merge models
!mergekit-yaml config.yaml merge --copy-tokenizer --allow-crimes --out-shard-size 1B --lazy-unpickl

现在,模型已经融合并保存在 merge 目录中。在上传之前,我们可以创建一个包含复现该模型融合操作所需信息的 README 文件。以下代码块定义了一个 Jinja 模板,并自动将模型融合配置中的数据填入其中。

!pip install -qU huggingface_hubfrom huggingface_hub import ModelCard, ModelCardData
from jinja2 import Templateusername = "mlabonne"template_text = """
---
license: apache-2.0
tags:
- merge
- mergekit
- lazymergekit
{%- for model in models %}
- {{ model }}
{%- endfor %}
---# {{ model_name }}{{ model_name }} is a merge of the following models using [mergekit](https://github.com/cg123/mergekit):{%- for model in models %}
* [{{ model }}](https://huggingface.co/{{ model }})
{%- endfor %}## 🧩 Configuration```yaml
{{- yaml_config -}}
```
"""# Create a Jinja template object
jinja_template = Template(template_text.strip())# Get list of models from config
data = yaml.safe_load(yaml_config)
if "models" in data:models = [data["models"][i]["model"] for i in range(len(data["models"])) if "parameters" in data["models"][i]]
elif "parameters" in data:models = [data["slices"][0]["sources"][i]["model"] for i in range(len(data["slices"][0]["sources"]))]
elif "slices" in data:models = [data["slices"][i]["sources"][0]["model"] for i in range(len(data["slices"]))]
else:raise Exception("No models or slices found in yaml config")# Fill the template
content = jinja_template.render(model_name=MODEL_NAME,models=models,yaml_config=yaml_config,username=username,
)# Save the model card
card = ModelCard(content)
card.save('merge/README.md')

现在我们有了 model card ,就可以将整个文件夹推送到 HuggingFace Hub。

from google.colab import userdata
from huggingface_hub import HfApiusername = "mlabonne"# Defined in the secrets tab in Google Colab
api = HfApi(token=userdata.get("HF_TOKEN"))api.create_repo(repo_id=f"{username}/{MODEL_NAME}",repo_type="model"
)
api.upload_folder(repo_id=f"{username}/{MODEL_NAME}",folder_path="merge",
)

该模型现在可以在 Hugging Face Hub 上找到,位于 mlabonne/Marcoro14–7B-slerp[25]。在另一个 notebook 中,我们可以使用以下代码尝试在免费的 T4 GPU 上运行该模型:

!pip install -qU transformers acceleratefrom transformers import AutoTokenizer
import transformers
import torchmodel = "mlabonne/Marcoro14-7B-slerp"
messages = [{"role": "user", "content": "What is a large language model?"}]tokenizer = AutoTokenizer.from_pretrained(model)
prompt = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True
)
pipeline = transformers.pipeline("text-generation",model=model,torch_dtype=torch.float16,device_map="auto",
)outputs = pipeline(prompt, max_new_tokens=256, do_sample=True, temperature=0.7, top_k=50, top_p=0.95)

我们向 LLM 提出了"What is a Large Language Model?"这个问题,并获得了这样的输出结果:

A large language model is a type of artificial intelligence (AI) system that has been trained on vast amounts of text data. It’s designed to understand and generate human-like language, making predictions on what words or phrases might come next in a sentence or document. These models use complex algorithms and neural network architectures to learn from the data and improve their performance over time. Some well-known large language models include GPT-3 from OpenAI and BERT from Google.

融合后的模型看起来不错,但我们需要更全面的评估。对于这种通用型模型,有一些有趣的基准测试:

  1. Chatbot Arena[26],它通过人类的投票编制 LLMs 排行榜。人们对不同语言模型的表现进行投票,然后使用 Elo 算法对这些模型进行排名。
  2. MT-bench[26],它使用 GPT-4 作为评判员,对一组多轮问题上的模型回答进行评分。
  3. NousResearch benchmark suite[27],它汇总了四个基准测试:AGIEval、GPT4ALL、TruthfulQA 和 Bigbench。GPT4ALL 包括了 HellaSwag、OpenBookQA、Winogrande、ARC-Easy、ARC-Challenge、BoolQ 和 PIQA。
  4. Open LLM Leaderboard[28],它汇总了六个基准测试:ARC、HellaSwag、MMLU、Winogrande、GSM8K 和 TruthfulQA。

不幸的是,我们无法将该模型提交到 Chatbot Arena。不过,可以选择使用 Open LLM Leaderboard 和 NousResearch 基准测试对其进行评估。

我已经将该模型提交到了 Open LLM Leaderboard[28],它在该排行榜上被评为最佳的 7B 参数模型。以下是具体情况截图:

Image by author

Open LLM Leaderboard 的问题在于这些基准测试是公开的。这意味着人们可以在测试数据上训练语言模型,以获得更好的结果。融合这些最佳的模型,也会污染模型。可以肯定的是,Marcoro14-7B-slerp 受到了污染,而且这次融合中使用的一些模型应该是在这些评估测试集上训练过的。 如果你想创建最好的模型而非仅仅在排行榜上表现较好的模型,我建议只使用非融合的模型来创建自己的融合模型。

这就是为什么我们不能只依赖于 Open LLM Leaderboard。在 NousResearch benchmark suite 中,我使用了 🧐 LLM AutoEval [29]来自动计算评估分数。以下是与表现优秀的 OpenHermes-2.5-Mistral-7B [30]进行比较的结果:

Image by author

与该模型相比,我们在每项基准测试中都取得了显著进步。请注意, NousResearch benchmark suite 与 Open LLM Leaderboard 共享了一些评估任务:ARC-Challenge,TruthfulQA,HellaSwag和Winogrande。据我所知,Bigbench是唯一完全不同的基准测试(如果情况不是这样,请随时去原文链接与作者联系)。然而,在此次模型融合中使用的模型之一仍可能是在Bigbench的评测数据集上训练过的。

03 总结

在这篇文章中,我们介绍了使用四种不同的方法去融合 LLMs 。详细说明了 SLERP、TIES、DARE 和 passthrough 的工作原理,并提供了相关的配置示例。最后,我们通过 mergekit 库使用SLERP方法训练出了 Marcoro14–7B-slerp ,并将其上传到 Hugging Face Hub 。我们在两个基准套件上都获得了出色的性能:Open LLM Leaderboard(该模型是该榜单性能最佳的 7B 模型)和NousResearch。

Thanks for reading!

END

参考资料

[1]https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard

[2]https://github.com/cg123/mergekit

[3]https://huggingface.co/mlabonne/Marcoro14-7B-slerp

[4]https://github.com/mlabonne/llm-course/blob/main/Mergekit.ipynb

[5]https://colab.research.google.com/drive/1_JS7JKJAQozD48-LhYdegcuuZ2ddgXfr?usp=sharing

[6]https://colab.research.google.com/drive/1obulZ1ROXHjYLn6PPZJwRR6GzgQogxxb?usp=sharing

[7]https://www.linkedin.com/in/charles-goddard-7b6797b/

[8]https://github.com/cg123/mergekit/tree/1011ef3a84e4c5545473602baf7ef32d535044a9#linear

[9]https://arxiv.org/abs/2212.04089

[10]https://huggingface.co/collections/osanseviero/model-merging-65097893623330a3a51ead66

[11]https://huggingface.co/EmbeddedLLM/Mistral-7B-Merge-14-v0.1

[12]https://huggingface.co/OpenPipe/mistral-ft-optimized-1218

[13]https://huggingface.co/mlabonne/NeuralHermes-2.5-Mistral-7B

[14]https://huggingface.co/mlabonne/NeuralPipe-7B-slerp

[15]https://arxiv.org/abs/2306.01708

[16]https://huggingface.co/Weyaxi/OpenHermes-2.5-neural-chat-7b-v3-1-7B

[17]https://huggingface.co/mlabonne/NeuralPipe-7B-ties

[18]https://arxiv.org/abs/2311.03099

[19]https://github.com/cg123/mergekit/issues/26

[20]https://huggingface.co/mlabonne/Daredevil-7B

[21]https://huggingface.co/zyh3826/GML-Mistral-merged-v1

[22]https://huggingface.co/mlabonne/NeuralPipe-9B-merged

[23]https://huggingface.co/AIDC-ai-business/Marcoroni-7B-v3

[24]https://huggingface.co/EmbeddedLLM/Mistral-7B-Merge-14-v0.1

[25]https://huggingface.co/mlabonne/Marcoro14-7B-slerp

[26]https://chat.lmsys.org/

[27]https://github.com/teknium1/LLM-Benchmark-Logs

[28]https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard

[29]https://github.com/mlabonne/llm-autoeval

[30]https://huggingface.co/teknium/OpenHermes-2.5-Mistral-7B

原文链接:

https://towardsdatascience.com/merge-large-language-models-with-mergekit-2118fb392b54

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

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

相关文章

Ansible playbook 剧本部署WEB NFS rsync sersync(及时监控)架构

ansible playbook剧本介绍&#xff1a; playbook 是ansible用于配置&#xff0c;部署和管理被节点的剧本 由一个或多个模块组成&#xff0c;完成统一的目的&#xff0c;实现自动化操作 剧本编写需遵循yaml语法 yaml的三要素&#xff1a; 缩进&#xff1a;两个字符&#xff0c;默…

【Vue3】toRefs和toRef在reactive中的一些应用

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

C++模板->模板的概念、函数模板基本语法、函数模板注意事项、普通函数与函数模板区别、普通函数与函数模板调用规则、模板的局限性

#include<iostream> using namespace std; //交换两个整型函数 void swapInt(int& a, int& b) { int temp a; a b; b temp; } //交换两个浮点型函数 void swapDouble(double& a, double& b) { double temp a; a b; b te…

MATLAB中gtext函数用法

目录 语法 说明 示例 使用鼠标将文本添加到图窗 指定字体大小和颜色 在创建后修改文本 gtext函数的功能是使用鼠标将文本添加到图窗。 语法 gtext(str) gtext(str,Name,Value) t gtext(___) 说明 gtext(str) 在使用鼠标选择的位置插入文本 str。当将鼠标指针悬停在图…

3个wordpress中文企业主题模板

农业畜牧养殖wordpress主题 简洁大气的农业畜牧养殖wordpress主题&#xff0c;农业农村现代化&#xff0c;离不开新农人、新技术。 https://www.jianzhanpress.com/?p3051 老年公寓wordpress主题 浅绿色简洁实用的老年公寓wordpress主题&#xff0c;适合做养老业务的老年公…

高标准农田仪器设备

在当今社会中&#xff0c;农业已经逐渐走向了一条科技化、智能化的道路。高标准农田建设成为了现代化农业发展的一个重要方向。为了更好地提高农产品的产量和品质&#xff0c;科技人员们不断地在农田设备上进行创造性的改进与升级&#xff0c;以达到更加高效、节能、环保、智能…

【C语言】注释

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…

【国际化】用JQuery-i18next的国际化demo,引入json

参考&#xff1a; 使用 i18next 的 jQuery 国际化 &#xff08;i18n&#xff09; 渐进式指南 (locize.com) i18next-http-backend/example/jquery/index.html at master i18next/i18next-http-backend (github.com) 文档 可能需要解决一下跨域问题&#xff0c;因为浏览器读取本…

Unity学习之Unity中的MVC思想

文章目录 1 前言2 MVC的基本概念3 不使用MVC思想制作UI逻辑3.1 拼面板3.2 面板脚本3.3 角色面板逻辑3.4 角色升级 4 使用MVC思想制作UI逻辑4.1 Model数据脚本4.2 View界面脚本4.2.1 MainView主界面4.2.2 RoleView 角色面板界面 4.3 Controller业务逻辑脚本4.3.1 MainController…

phaseDNN文章解读

文章DOI: https://doi.org/10.48550/arXiv.1905.01389 作者是 Southern Methodist University 的Wei Cai 教授 A Parallel Phase Shift Deep Neural Network for Adaptive Wideband Learning 一种并行移相深度神经网络来自适应学习宽带频率信号 20190514 核心思想&#xff1a;…

跟着pink老师前端入门教程(JavaScript)-day05

六、语句 &#xff08;一&#xff09;表达式和语句 1、表达式 表达式是可以被求值的代码&#xff0c;JavaScript 引擎会将其计算出一个结果。 2、语句 语句是一段可以执行的代码。 比如&#xff1a; prompt() 可以弹出一个输入框&#xff0c;还有 if语句 for 循环语句等…

Socks5代理IP详解:优势与应用场景

Socks5代理IP作为网络代理技术的前沿选择&#xff0c;其在多方面的优势使其在2024年成为了热门选择。 一、Socks5代理IP的核心特性 1、Socks5代理IP与其他代理类型的比较 HTTP代理设计用于web浏览&#xff0c;仅支持HTTP和HTTPS协议。 Socks4代理支持更多类型的网络协议&…

欧拉回路和欧拉路径

在一张图中&#xff0c;从一个点出发每条边经过且只经过一次得到的路径&#xff0c;如果最后回到起点&#xff0c;那么就是欧拉回路&#xff0c;如果最后没有回到起点&#xff0c;那么得到的就是欧拉路径。 在无向图中&#xff0c;欧拉路径满足的要求是&#xff0c;除了起点和…

DM数据库学习之路(十六)DEM部署DM8DPC集群

DEM部署DPC集群 DPC准备工作 在所有安装DPC服务器上部署dmagent&#xff0c;dmagent的运行环境需要依赖JAVA环境&#xff0c;JAVA版本必须为JAVA1.8。 创建用户 所有安装DPC服务器&#xff0c;手工建dmdba用户 # groupadd dinstall # useradd -g dinstall -d /home/dmdba…

并发编程之深入理解Java线程

并发编程之深入理解Java线程 线程基础知识 线程和进程 进程 程序由指令和数据组成、但这些指令要运行&#xff0c;数据要读写&#xff0c;就必须要将指令加载至CPU、数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理IO的…

Jmeter内置变量 vars 和props的使用详解

JMeter是一个功能强大的负载测试工具&#xff0c;它提供了许多有用的内置变量来支持测试过程。其中最常用的变量是 vars 和 props。 vars 变量 vars 变量是线程本地变量&#xff0c;它们只能在同一线程组内的所有线程中使用&#xff08;线程组内不同线程之间变量不共享&#…

模型转换案例学习:等效替换不支持算子

文章介绍 Qualcomm Neural Processing SDK &#xff08;以下简称SNPE&#xff09;支持Caffe、ONNX、PyTorch和TensorFlow等不同ML框架的算子。对于某些特定的不支持的算子&#xff0c;我们介绍一种算子等效替换的方法来完成模型转换。本案例来源于https://github.com/quic/qidk…

并发编程(2)基础篇-管程

4 共享模型之管程 本章内容 共享问题synchronized线程安全分析Monitorwait/notify线程状态转换活跃性Lock 4.1 共享带来的问题 4.1.1 小故事 老王&#xff08;操作系统&#xff09;有一个功能强大的算盘&#xff08;CPU&#xff09;&#xff0c;现在想把它租出去&#xff…

2024 全国水科技大会暨第二届智慧水环境管理与技术创新论坛

论坛二&#xff1a;第二届智慧水环境管理与技术创新论坛 召集人&#xff1a;刘炳义 武汉大学智慧水业研究所所长、教授 为贯彻落实中共中央国务院印发《数字中国建设整体布局规划》和国务院关于印发《“十四五”数字经济发展规划》的通知&#xff0c;推动生态环境智慧治理&…

L2 清点代码库----PTA(疑问)

上图转自新浪微博&#xff1a;“阿里代码库有几亿行代码&#xff0c;但其中有很多功能重复的代码&#xff0c;比如单单快排就被重写了几百遍。请设计一个程序&#xff0c;能够将代码库中所有功能重复的代码找出。各位大佬有啥想法&#xff0c;我当时就懵了&#xff0c;然后就挂…