2024年7月


大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是
瑞萨RA8系列高性能MCU开发上手体验

我们知道瑞萨半导体的通用 MCU 产品线主要包含基于自有内核 8/16bit RL78 系列以及 32bit RX 系列,还有这两年明显增加研发投入的基于 Arm Cortex-M 内核的 RA、Synergy 系列,当然还有 RISC-V 内核产品(基于 AndesCore N22/D25F 的 ASSP EASY 系列和自研内核的 R9A02G021)。

瑞萨这些 MCU 产品中,痞子衡最感兴趣的当然是基于 Cortex-M85 内核的 RA8 系列,因为它们的性能比较接近痞子衡深耕的 i.MX RT 系列。最近痞子衡手头搞到了一块 EK-RA8M1 开发板,闲着也是闲着,索性就玩玩看,了解一下友商竞品,那我们就从瑞萨提供的软件开发环境以及支持包角度先浅玩一把:

一、RA8系列简介

从2023年10月到2024年1月,瑞萨陆续发布了三款基于 Cortex-M85 内核的产品:RA8M1(通用)、RA8D1(显示、语音、AI)、RA8T1(电机),这么短时间连推三款,熟悉半导体研发节奏的朋友都应该能猜到,这三个很有可能是基于一条主线下的 Phantom 项目(纯属瞎猜,不负责任)。

从如下 RA8M1 模块框图来看,除了 480MHz 高主频以及 Safety 和 Security 方面是超配的,其它常见外设算是标准配置,此外在 System 一栏里还看到 Low Power Modes,看起来这款高性能 MCU 也为低功耗方面做了设计考虑。

二、开发支持三大件

2.1 开发环境e² studio

e² studio 是瑞萨自家的基于 Eclipse 的集成开发环境(IDE),除了 Eclipse 自己强大的代码编辑器外,e² studio 还提供了丰富的扩展功能,e² studio 涵盖了从下载示例代码到调试的所有开发过程。如果不想装免费的 e² studio,坚持用你熟悉的 IAR,Keil MDK,当然也是可以的。

官网地址:
https://www.renesas.cn/cn/zh/software-tool/e-studio

2.2 软件包FSP

灵活配置软件包 (FSP) 即是瑞萨软件团队设计的 SDK,为什么叫 FSP 而不是 SDK,后面痞子衡会专门出一篇文章详细介绍。FSP 包括高性能、低内存占用的的 HAL 驱动程序,也包含集成了 Azure RTOS 和 FreeRTOS 的中间件协议栈。

官网地址:
https://www.renesas.cn/cn/zh/software-tool/flexible-software-package-fsp

2.3 评估板EK

痞子衡手里的 EK-RA8M1 评估套件可通过瑞萨的灵活软件包 (FSP) 和 e2 studio IDE,来快速评估 RA8M1 MCU 产品特性。这个评估板上也包含了板载调试器(主控是 RA4M2,预烧录的是 JLink 固件)以及虚拟串口,我们只需要插上 USB 就能供电下载调试。

官网地址:
https://www.renesas.cn/cn/zh/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra8m1-evaluation-kit-ra8m1-mcu-group

三、试跑LPM例程

有了 EK-RA8M1 评估板,我们现在需要安装 IDE 和 FSP,可以直接从如下瑞萨官方 github 地址来下载。setup_fsp_v5_4_0_e2s_v2024-04.exe 包含了 IDE 和 FSP,可以一键安装。 这里需要表扬一下,瑞萨在 FSP 软件开源这一块走得还是比较前面的。

IDE&FSP下载地址:
https://github.com/renesas/fsp/releases

瑞萨 FSP 包里主要是 HAL、BSP 驱动以及各种中间件代码,并不包含应用例程,我们还需要单独下载如下例程包:

FSP配套例程下载地址:
https://github.com/renesas/ra-fsp-examples/releases

有了 r20an0715eu0111-ek-ra8m1-exampleprojects.zip 包后将其解压,然后打开 e² studio,在菜单栏里 File -> Import -> General/Existing Projects into Workspace 选择解压后文件夹路径,就可以导入想跑的例程了。痞子衡正好最近在研究功耗,那就导入一个 lpm 例程吧:

编译下载 lpm 例程进 EK-RA8M1 板,打开串口调试助手,便可以看到例程跑起来了。从打印结果来看,LPM 例程设计得还是比较人性化的,四种功耗模式自动按序切换,每个模式下会停留一小段时间,非常便于测量电流(结果已经加进图中,需要注意的是测量过程中 VCC 一直维持 3.33V 没掉电)

甚至在 EK-RA8M1 板设计时就已经预留好 VCC 电流测量点 TP1,3 了(只需要把电阻 R3 拿掉即可),这个必须点赞,软硬件协作设计在这一刻得到了充分体现。

至此,瑞萨RA8系列高性能MCU开发上手体验痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的
博客园主页

CSDN主页

知乎主页

微信公众号
平台上。

微信搜索"
痞子衡嵌入式
"或者扫描下面二维码,就可以在手机上第一时间看了哦。

本文分享自华为云社区
《【昇思25天学习打卡营打卡指南-第二十四天】基于 MindSpore 实现 BERT 对话情绪识别》
,作者:JeffDing。

模型简介

BERT全称是来自变换器的双向编码器表征量(Bidirectional Encoder Representations from Transformers),它是Google于2018年末开发并发布的一种新型语言模型。与BERT模型相似的预训练语言模型例如问答、命名实体识别、自然语言推理、文本分类等在许多自然语言处理任务中发挥着重要作用。模型是基于Transformer中的Encoder并加上双向的结构,因此一定要熟练掌握Transformer的Encoder的结构。

BERT模型的主要创新点都在pre-train方法上,即用了Masked Language Model和Next Sentence Prediction两种方法分别捕捉词语和句子级别的representation。

在用Masked Language Model方法训练BERT的时候,随机把语料库中15%的单词做Mask操作。对于这15%的单词做Mask操作分为三种情况:80%的单词直接用[Mask]替换、10%的单词直接替换成另一个新的单词、10%的单词保持不变。

因为涉及到Question Answering (QA) 和 Natural Language Inference (NLI)之类的任务,增加了Next Sentence Prediction预训练任务,目的是让模型理解两个句子之间的联系。与Masked Language Model任务相比,Next Sentence Prediction更简单些,训练的输入是句子A和B,B有一半的几率是A的下一句,输入这两个句子,BERT模型预测B是不是A的下一句。

BERT预训练之后,会保存它的Embedding table和12层Transformer权重(BERT-BASE)或24层Transformer权重(BERT-LARGE)。使用预训练好的BERT模型可以对下游任务进行Fine-tuning,比如:文本分类、相似度判断、阅读理解等。

对话情绪识别(Emotion Detection,简称EmoTect),专注于识别智能对话场景中用户的情绪,针对智能对话场景中的用户文本,自动判断该文本的情绪类别并给出相应的置信度,情绪类型分为积极、消极、中性。 对话情绪识别适用于聊天、客服等多个场景,能够帮助企业更好地把握对话质量、改善产品的用户交互体验,也能分析客服服务质量、降低人工质检成本。

安装mindnlp

pip install mindnlp

下面以一个文本情感分类任务为例子来说明BERT模型的整个应用过程。

import os

import mindspore
frommindspore.dataset import text, GeneratorDataset, transformsfrommindspore import nn, contextfrommindnlp._legacy.engine import Trainer, Evaluatorfrommindnlp._legacy.engine.callbacks import CheckpointCallback, BestModelCallbackfrommindnlp._legacy.metrics import Accuracy

# prepare dataset
classSentimentDataset:"""Sentiment Dataset"""def __init__(self, path):
self.path
=path
self._labels, self._text_a
=[], []
self._load()

def _load(self):
with open(self.path,
"r", encoding="utf-8") asf:
dataset
=f.read()
lines
= dataset.split("\n")for line in lines[1:-1]:
label, text_a
= line.split("\t")
self._labels.append(
int(label))
self._text_a.append(text_a)

def __getitem__(self, index):
returnself._labels[index], self._text_a[index]

def __len__(self):
return len(self._labels)

数据集

这里提供一份已标注的、经过分词预处理的机器人聊天数据集,来自于百度飞桨团队。数据由两列组成,以制表符(’\t’)分隔,第一列是情绪分类的类别(0表示消极;1表示中性;2表示积极),第二列是以空格分词的中文文本,如下示例,文件为 utf8 编码。

label–text_a

0–谁骂人了?我从来不骂人,我骂的都不是人,你是人吗 ?

1–我有事等会儿就回来和你聊

2–我见到你很高兴谢谢你帮我

这部分主要包括数据集读取,数据格式转换,数据 Tokenize 处理和 pad 操作。

wget https://baidu-nlp.bj.bcebos.com/emotion_detection-dataset-1.0.0.tar.gz -O emotion_detection.tar.gz
tar xvf emotion_detection.tar.gz

数据加载和数据预处理

新建 process_dataset 函数用于数据加载和数据预处理,具体内容可见下面代码注释。

import numpy asnp

def process_dataset(source, tokenizer, max_seq_len
=64, batch_size=32, shuffle=True):
is_ascend
= mindspore.get_context('device_target') == 'Ascend'column_names= ["label", "text_a"]

dataset
= GeneratorDataset(source, column_names=column_names, shuffle=shuffle)
# transforms
type_cast_op
=transforms.TypeCast(mindspore.int32)
def tokenize_and_pad(text):
ifis_ascend:
tokenized
= tokenizer(text, padding='max_length', truncation=True, max_length=max_seq_len)else:
tokenized
=tokenizer(text)return tokenized['input_ids'], tokenized['attention_mask']
# map dataset
dataset
= dataset.map(operations=tokenize_and_pad, input_columns="text_a", output_columns=['input_ids', 'attention_mask'])
dataset
= dataset.map(operations=[type_cast_op], input_columns="label", output_columns='labels')
# batch dataset
ifis_ascend:
dataset
=dataset.batch(batch_size)else:
dataset
= dataset.padded_batch(batch_size, pad_info={'input_ids': (None, tokenizer.pad_token_id),'attention_mask': (None, 0)})return dataset

昇腾NPU环境下暂不支持动态Shape,数据预处理部分采用静态Shape处理:

frommindnlp.transformers import BertTokenizer
tokenizer
= BertTokenizer.from_pretrained('bert-base-chinese')

tokenizer.pad_token_id

dataset_train
= process_dataset(SentimentDataset("data/train.tsv"), tokenizer)
dataset_val
= process_dataset(SentimentDataset("data/dev.tsv"), tokenizer)
dataset_test
= process_dataset(SentimentDataset("data/test.tsv"), tokenizer, shuffle=False)

print(next(dataset_train.create_tuple_iterator()))

模型构建

通过 BertForSequenceClassification 构建用于情感分类的 BERT 模型,加载预训练权重,设置情感三分类的超参数自动构建模型。后面对模型采用自动混合精度操作,提高训练的速度,然后实例化优化器,紧接着实例化评价指标,设置模型训练的权重保存策略,最后就是构建训练器,模型开始训练。

frommindnlp.transformers import BertForSequenceClassification, BertModelfrommindnlp._legacy.amp import auto_mixed_precision

#
set bert config and define parameters fortraining
model
= BertForSequenceClassification.from_pretrained('bert-base-chinese', num_labels=3)
model
= auto_mixed_precision(model, 'O1')

optimizer
= nn.Adam(model.trainable_params(), learning_rate=2e-5)

metric
=Accuracy()
# define callbacks to save checkpoints
ckpoint_cb
= CheckpointCallback(save_path='checkpoint', ckpt_name='bert_emotect', epochs=1, keep_checkpoint_max=2)
best_model_cb
= BestModelCallback(save_path='checkpoint', ckpt_name='bert_emotect_best', auto_load=True)

trainer
= Trainer(network=model, train_dataset=dataset_train,
eval_dataset
=dataset_val, metrics=metric,
epochs
=5, optimizer=optimizer, callbacks=[ckpoint_cb, best_model_cb])
# start training
trainer.run(tgt_columns
="labels")

模型验证

将验证数据集加再进训练好的模型,对数据集进行验证,查看模型在验证数据上面的效果,此处的评价指标为准确率。

evaluator = Evaluator(network=model, eval_dataset=dataset_test, metrics=metric)
evaluator.run(tgt_columns
="labels")

模型推理

遍历推理数据集,将结果与标签进行统一展示。

dataset_infer = SentimentDataset("data/infer.tsv")

def predict(text, label
=None):
label_map
= {0: "消极", 1: "中性", 2: "积极"}

text_tokenized
=Tensor([tokenizer(text).input_ids])
logits
=model(text_tokenized)
predict_label
= logits[0].asnumpy().argmax()
info
= f"inputs: '{text}', predict: '{label_map[predict_label]}'" if label isnot None:
info
+= f", label: '{label_map[label]}'"print(info)frommindspore import Tensorfor label, text indataset_infer:
predict(text, label)

自定义推理数据集

自己输入推理数据,展示模型的泛化能力。

predict("家人们咱就是说一整个无语住了 绝绝子叠buff")

点击关注,第一时间了解华为云新鲜技术~

〇、前言

本文首先介绍了 Linux 中文件的结构,将全部文件夹罗列并介绍了大概的用途;

然后通过实例介绍了文件夹相关的常用操作,仅供参考。

一、Linux 系统的文件结构

列一下系统全部文件夹:

/ 文件系统的入口,最高一级目录
/bin 【基础系统命令】基础系统所需要的命令位于此目录,如:ls、cp、mkdir 等二进制可执行命令
/sbin 【系统管理命令】存放的是系统管理员使用的管理程序
/boot 包含 【Linux 内核及系统引导程序】所需要的文件
/dev 【设备文件】存储目录,比如声卡、磁盘等
/etc 存放【系统程序或者一般工具】的管理和配置文件
/etc/rc.d 启动的配置文件和脚本
/home 普通【用户默认存放目录】,它们以 /home/username 的方式存在
/lib 【库文件】存放目录,这里包含了系统程序所需要的所有共享库文件,作用类似 windows 里的 .dll 文件
/lost+found 这个目录平时是空的,系统【非正常关机而留下“无家可归”的文件】(windows下叫什么.chk)就在这里
/media 【即插即用型存储设备】的挂载点,自动在这个目录下创建
/mnt 一般是用于【让用户临时挂载其他的文件系统】
/opt 表示的是【可选择的意思】,有些软件包也会被安装在这里
/proc 操作系统运行时,【进程信息、硬件信息】存放在这里,可直接访问这个目录来获取系统信息
/root 系统管理员用户 root 的主目录
/sbin 大多是涉及【系统管理的命令】的存放,是超级权限用户 root 的可执行命令
/tmp 公用【临时文件】目录,有时用户运行程序的时候,会产生临时文件
/var 某些大文件的溢出区,比如用来存放【系统日志】的目录
/usr 最庞大的目录,【要用到的应用程序和文件】几乎都在这个目录
/usr/bin 众多的应用程序
/usr/sbin 超级用户的一些管理程序
/usr/doc Linux 文档
/usr/include Linux 下开发和编译应用程序所需要的头文件
/usr/lib 常用的动态链接库和软件包的配置文件
/usr/man 帮助文档
/usr/src 源代码,linux 内核的源代码就放在 /usr/src/linux 里
/usr/local/bin 本地增加的命令
/usr/local/lib 本地增加的库

二、文件夹相关操作

2.1 cd 切换当前文件夹

cd cd 后为空,表示回到
[root@localhost ~]#
,即:/root
cd /usr/local cd 后跟
绝对路径
,直接进入,
无论当前在哪个文件夹
cd local/projectname cd 后跟
相对路径
,以当前文件夹为基础,进入相对路径,
和当前所在文件夹紧密相关
cd .. 两个点,表示返回上一级文件夹
cd ../.. 表示返回上两级文件夹

通过 pwd 命令查看当前文件夹路径:

[root@localhost ~]# cd  ..
[root@localhost /]# cd
[root@localhost ~]# pwd
/root
[root@localhost ~]# 

2.2 mkdir 创建文件夹

mkdir [-p] [Linux路径]
  • Linux 路径必填,即:要创建的文件夹的路径,相对或绝对路径均可。
  • -p 选项可选,表示
    自动创建不存在的父目录
    ,适用于创建连续多层级的目录。

关于路径:

  • 开头为 /
    :表示绝对路径。如:/usr/local/projectname/v1.0
  • 开头为文件夹名称
    :表示相对路径。如:projectname/v1.0

测试一下:(当所创建的目录跨级别时,不加 -p 参数会创建失败,以及绝对路径和相对路径)

[root@localhost local]# mkdir /usr/local/projectname/v1.0
mkdir: cannot create directory ‘/usr/local/projectname/v1.0’: No such file or directory
[root@localhost local]# mkdir -p /usr/local/projectname/v1.0
[root@localhost local]# ls
bin  etc  games  include  lib  lib64  libexec  projectname  sbin  share  src  usr
[root@localhost local]# mkdir -p projectname/v2.0
[root@localhost local]# cd projectname
[root@localhost projectname]# ls
v1.0  v2.0
[root@localhost projectname]#

2.3 创建文件的三种方法:">"重定向符号、touch、echo

touch [Linux 路径]
  • 其中唯一的参数,要新增的文件路径,必填。
[root@localhost /]# cd usr/local/projectname/v1.0
[root@localhost v1.0]# > jsons.json
[root@localhost v1.0]# touch logs.log
[root@localhost v1.0]# echo "文件初始内容" >chinatext.txt
[root@localhost v1.0]# ls
chinatext.txt  logs.log  text.txt
[root@localhost v1.0]# ls -l
total 8
-rw-r--r-- 1 root root 19 Nov  6 16:53 chinatext.txt
-rw-r--r-- 1 root root  0 Nov  6 16:44 jsons.json
-rw-r--r-- 1 root root  0 Nov  6 16:34 logs.log
[root@localhost v1.0]# cat chinatext.txt
文件初始内容
[root@localhost v1.0]#

2.4 复制、移动、删除文件或文件夹

2.4.1 概念解析:硬连接(Hard Link)、符号链接(Symbolic Link)(软链接)

硬链接

文件还是同一个,只是入口不同,删除某一个入口,不影响源文件,只有删掉最后一个链接,文件才会被彻底删除。

创建一个
与原文件任何信息都相同的目标文件
(文件名可能不同,可自由设定),只有路径不同。一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以
防止“误删”
的功能。只删除某一个链接不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。文件夹无法创建硬链接。
不能跨分区创建。

// 命令:
ln filepath1 filepath2
// filepath2 是对 filepath1 的硬连接
// 当删掉 filepath1 时,filepath2 仍然有效

软链接

相当于创建了一个
指向原文件的“快捷方式”
,其中索引信息,创建日期等均不相同。
源文件删除后,快捷方式也就无效了。

这个软连接文件实际上是一个文本文件,其中包含的有另一文件的位置信息。
可以跨分区创建,但是对文件夹无效。

// 命令:
ln -s  filepath1 filepath2
// filepath2 是对源目录 filepath1 的软连接
// 当删掉源目录 filepath1 时,filepath2 无效

2.4.2 cp 复制/粘贴

cp [选项] [路径1-源] [路径2-目标]

选项内容可省略,详情如下:

  • -d:当复制
    符号链接(软链接)
    时,把目标文件或目录也建立为符号连接,并指向与源文件或目录连接的原始文件或目录;
  • -l:对源文件建立
    硬链接
    ,而非复制文件;(Hard Link)
  • -s:对源文件建立
    符号链接(软链接)
    ,而非复制文件;(Symbolic Link)
  • -f:强行复制文件或目录,不论目标文件或目录是否已存在;
  • -i:覆盖既有文件之前先询问用户;
  • -R/r:递归处理,将指定目录下的所有文件与子目录一并处理;
  • -b:覆盖已存在的文件目标前将目标文件备份;
  • -v:详细显示命令执行的操作。

路径1 为源文件路径,路径2 为目标路径。

如下测试,通过 -r 配置选项,将文件夹 v1.0 以及其下的文件,全部复制到 v2.0 文件夹中:

[root@localhost projectname]# cd v1.0
[root@localhost v1.0]# ls
chinatext.txt  logs.log  text.txt
[root@localhost v1.0]# cd ../
[root@localhost projectname]# cd v2.0
[root@localhost v2.0]# ls
[root@localhost v2.0]# cd ../
[root@localhost projectname]# ls
v1.0  v2.0
[root@localhost projectname]# cp v1.0/chinatext.txt v2.0/chinatext.txt
[root@localhost projectname]# cd v2.0
[root@localhost v2.0]# ls
chinatext.txt
[root@localhost v2.0]# cat chinatext.txt
文件初始内容
[root@localhost v2.0]# cd ../
[root@localhost projectname]# cp -r v1.0 v2.0
[root@localhost projectname]# cd v2.0
[root@localhost v2.0]# ls
chinatext.txt  v1.0
[root@localhost v2.0]# 

参考: https://www.cnblogs.com/uncle-qi/p/9359741.html

2.4.3 mv 移动/重命名

mv [路径1] [路径2]

路径1 表示被移动的文件或文件夹;路径2 标识要移动到的目标位置,若目标文件不存在则按照路径中名字移动,若已存在则提示确认替换。

[root@localhost v1.0]# cat text.txt
文件初始内容
[root@localhost v1.0]# >textnull.txt
[root@localhost v1.0]# ls
textnull.txt  text.txt
[root@localhost v1.0]# mv textnull.txt text.txt
mv: overwrite ‘text.txt’? 
[root@localhost v1.0]# cat text.txt
文件初始内容
[root@localhost v1.0]# mv textnull.txt text.txt
mv: overwrite ‘text.txt’? y
[root@localhost v1.0]# cat text.txt
[root@localhost v1.0]# ls
text.txt
[root@localhost v1.0]# 

2.4.4 rm 删除

rm [选项] filepath1 filepath2 filepath3 ... filepathN

选项有三种,如下:

  • -f:强制删除(force),系统不再提示确认,而是直接删除目标文件或目录,和 -i 选项相反。
  • -i:和 -f 相反,在删除文件或目录之前,系统会逐一询问,输入 y 回车确认删除,防止误删。
  • -r:递归删除,主要用于删除目录,可删除指定目录及包含的所有内容,包括所有的子目录和文件。

filepath1:表示文件路径,可同时列出多个路径通过空格分隔,一次性删除。

下面是一个删除文件夹 v2.0 及其下子文件夹及文件的实例:

[root@localhost v1.0]# ls
jsons.json  temp.txt  textnull.txt  text.txt  v2.0  xmls.xml
[root@localhost v1.0]# rm  -r  v2.0
rm: descend into directory ‘v2.0’? y
rm: remove regular file ‘v2.0/chinatext.txt’? y
rm: descend into directory ‘v2.0/v1.0’? y
rm: remove regular empty file ‘v2.0/v1.0/text.txt’? y
rm: remove regular empty file ‘v2.0/v1.0/logs.log’? y
rm: remove regular empty file ‘v2.0/v1.0/jsons.json’? y
rm: remove regular file ‘v2.0/v1.0/xmls.xml’? y
rm: remove regular file ‘v2.0/v1.0/chinatext.txt’? y
rm: remove regular empty file ‘v2.0/v1.0/temp.txt’? y
rm: remove directory ‘v2.0/v1.0’? y
rm: remove directory ‘v2.0’? y
[root@localhost v1.0]# ls
jsons.json  temp.txt  textnull.txt  text.txt  xmls.xml
[root@localhost v1.0]#

参考:
https://www.cnblogs.com/KeFeng/p/17300667.html

2.5 文件查找 find

文件查找有两种关键字:locate(
非实时
查找)、find(
实时
查找)。

locate 命令的优点是查找速度快,因为它实际上是在一个名为 /var/lib/mlocate/mlocate.db 的特殊数据库中查找文件。
这个数据库会定期更新,因此它可以快速找到文件的位置。但是,由于 locate 命令依赖于这个数据库,所以如果文件是在最近一次数据库更新之后创建或删除的,locate 命令可能找不到它们。因此
除非是性能要求非常高的场景,建议直接用 find 命令
。本章节也主要以 find 为例进行介绍。

find 是实时查找工具,通过遍历指定路径完成文件查找。

特点:实时查找、精确查找、查找速度较 locate 略慢、查找条件丰富、可能只搜索用户具备的读取和执行权限目录。

find [选项]...[查询路径] [查找条件] [处理动作]
  • 查找路径:指定具体目标路径,默认为当前目录。
  • 查找条件:指定的查找标准,可以文件名、大小、类型、权限等标准进行;默认为找出指定路径下的所有文件。
  • 处理动作:对符合条件的文件做操作,默认输出到屏幕。

根据文件名查找:

// 语法示例:
find [起始路径] -name "被查找文件名"
// -name 选项表示,按照文件名搜索
// -iname 选项表示,按照文件名搜索,且不区分大小写
// 在被查找文件名参数上,支持使用通配符 * 来做模糊查询

根据文件大小查询:

// 语法示例:
find [起始路径] -size +/-n[kMG] "被查找文件名"
// +,- 表示大于和小于,缺省标识【等于】
// n 表示大小数字
// kMG 表示大小单位,k(小写字母)表示 kb,M 表示 MB,G 表示 GB
// 示例:
find / -size -10k  // 查找小于 10KB 的文件
find / -size 10k  // 查找等于 10KB 的文件
find / -size +100M // 查找大于 100MB 的文件

通过正则表达式查询:

// 语法示例:(查询文件后缀为 json 或 txt 的全部文件)
find [起始路径] -type f -regex '.*\(\.json\|\.txt\)'
// type 参数:f 代表普通文件,d 代表目录,l 代表符号链接,b 代表块设备文件,c 代表字符设备文件,p 代表管道文件,s 代表套接字文件
// regex 参数:正字表达式内容

多条件复合查询:

// 与:-a(默认多个条件是与关系)
// 或:-o
// 非:-not
// 语法示例:(查询类型为文件或路径)
find [起始路径] -type f -o -type d
// 语法示例:(查询类型为 txt 后缀的文件或包含 test 的路径)
find [起始路径] -type f  -regex '.*\.txt' -o -type d -regex '.*test'

按时间查询:

// 语法示例:
// 【近一天】修改过的文件:
find [起始路径] -type f -mtime -1
// -mtime:单位为【天】
// 【近十分钟】修改过的文件:
find [起始路径] -type f -mmin -10
// -mmin:单位为【分钟】

文件查询详情可参考: https://www.cnblogs.com/cn-leoblog/p/15707078.html

ComfyUI进阶:Comfyroll插件 (一)

前言:

学习ComfyUI是一场持久战,而Comfyroll Studio 是一款功能强大的自定义节点集合,专为 ComfyUI 用户打造,旨在提供更加丰富和专业的图像生成与编辑工具。借助这些节点,用户可以在静态图像的精细调整和动态动画的复杂构建方面进行深入探索。Comfyroll Studio 的节点设计简洁易用,功能强大,是每个希望提升 ComfyUI 使用体验的用户的必备选择。祝大家学习顺利,早日成为ComfyUI的高手!

目录

一、安装

二、CR Latent Batch Size节点

三、CR Image Output节点

四、CR Conditioning Mixer节点

五、CR Seed节点

六、CR Select Model节点

七、CR Combine Prompt节点

八、CR prompt Text节点

九、CR VAE Decode节点

十、Comfyroll Studio 基础工作流搭建

一、安装

方法一:

1.直接在ComfyUI界面打开Manager管理器

2.点击Custom Nodes Manager

1

3.搜索“Comfyroll”,点击Install。

2

4.重启ComfyUI

方法二:

1.打开
https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes

3

  1. 放到 custom_nodes文件夹

4

  1. 重启ComfyUI

方法三:

1.Civitai网站直接下载:
https://civitai.com/models/87609/comfyroll-custom-nodes-for-comfyui

5

2.节点检索:CR Image Output/CR Latent Batch Size/CR Conditioning Mixer/CR Select Model/CR Seed/CR Prompt Text/CR Combine Prompt/CR VAE Decode

二、CR Latent Batch Size节点

该节点是一个用于设置潜在空间批处理大小的节点。

6

输入:

Latent → 接收编码后的图像特征

参数:

batch_size → 定义一次处理过程中生成的图像数量。**根据硬件性能(如显存大小)和具体需求进行调整。**

输出:

LATENT → 将编码数据转换回可视化的图像

使用场景

· 批量生成图像:当你需要生成多个图像时,可以通过调整批处理大小来一次性生成所需数量的图像。

· 加快处理速度:在硬件允许的情况下,通过增大批处理大小,可以减少处理时间,从而提高工作效率。

· 实验与调优:在调整生成模型参数或进行图像生成实验时,可以通过批处理生成多张图像,以更好地观察和比较不同设置的效果。

总结来说,CR Latent Batch Size节点在 ComfyUI 中是一个非常有用的工具,允许用户根据需求批量生成图像,提高生成效率,并为各种图像生成任务提供更大的灵活性。

三、CR Image Output节点

该节点是一个用于管理和输出生成图像的节点,它在图像生成工作流中扮演着重要的角色,帮助存储、查看和处理生成的图像。

7

输入:

images → 加载预处理图像

参数:

output_type → 图像输出方式

file format → 选择输出图像的文件格式(如PNG、JPEG等)

输出:

trigger → 布尔值的输入

使用场景

· 批量生成图像保存:当你使用生成模型批量生成多张图像时,CR Image Output节点可以帮助你自动保存所有生成的图像到指定的目录中。

· 图像预处理和后处理:在图像生成的工作流中,CR Image Output节点可以作为中间节点,将生成的图像输出后,再传递给其他处理节点进行进一步处理,如图像增强、滤镜应用等。

· 格式转换和优化:在生成图像后,可以使用该节点将图像转换为特定的格式,并进行优化,以满足特定的应用需求(如网页显示、打印等)。

CR Image Output 节点在 ComfyUI 中提供了强大的图像输出管理功能,帮助高效地保存、管理和处理生成的图像。

四、CR Conditioning Mixer节点

该节点是一个用于混合不同条件输入的节点,它允许在生成图像时,将多个不同的条件(如文本描述、图像特征等)组合在一起,以创造更复杂和多样化的输出。

8

输入:

conditioning_1 → 接收用于指导图像生成过程的条件

conditioning_2 → 接收用于指导图像生成过程的条件

参数:

mix_method → 可以在三种不同的条件信息混合方法之间轻松切换

average_strength → 选择条件混合策略,例如加权平均、乘积等,以确定如何组合这些条件

输出:

CONDITIONING → 将混合后的条件发送到图像生成流程中的下一个节点

使用场景

· 文本与图像混合:用户可以将一个文本描述和一个图像特征混合在一起,生成既符合文本描述又带有图像特征的图像。

· 多文本描述:当用户希望生成包含多个文本描述特征的图像时,可以使用多个文本条件输入,并通过权重调整来平衡它们之间的影响。

· 风格迁移:将不同风格的图像特征混合在一起,生成具有多种风格特征的图像。

CR Conditioning Mixer节点将帮助你在 ComfyUI 中实现更加复杂和多样化的图像生成效果。

五、CR Seed节点

该节点是一个用于管理和控制随机种子的节点,随机种子在生成模型中起着至关重要的作用,因为它决定了生成过程的随机性,从而影响生成的图像结果。

9

10

参数:

seed → 输入种子数保持图片一致性

control_after_generate → 用于调整和控制种子数

输出:

seed → 控制随机性,将设置好的种子值传递给其他节点 (一般是K采样器)

show_help → 激活帮助信息或指导(可不连接)

使用场景

· 可重复性实验:在调试或对比不同生成模型或参数设置时,使用相同的种子值可以确保结果的一致性,方便对比分析。

· 多样性图像生成:通过设置不同的种子值,可以生成不同的图像,增加生成内容的多样性和创意。

· 批量生成图像:在批量生成图像时,可以使用一系列种子值,确保每张图像都有不同的特性。

CR Seed 节点在 ComfyUI 中控制生成图像的随机性,确保实验的可重复性,或生成多样化的图像。

六、CR Select Model节点

该节点是一个用于选择和加载生成模型的节点,这个节点允许在不同的模型之间切换,以便根据具体的生成任务和需求选择最合适的模型。

11

参数:

ckpt_name1 → 上传第一个checkpoint模型

ckpt_name2 → 上传第二个checkpoint模型

ckpt_name3 → 上传第三个checkpoint模型

ckpt_name4 → 上传第四个checkpoint模型

ckpt_name5 → 上传第五个checkpoint模型

select_model → 选择第几个模型用于图像生成或处理

输出:

MODEL → 用于发送选定模型信息到流程中的下一个节点

CLIP → 将选定的模型与CLIP相关的信息或功能连接起来

VAE → 将选定的模型与VAE解码器连接

ckpt_name → 传递被选定模型的名称

show_help → 激活帮助信息或指导,可不连接

使用场景

· 模型对比:在进行生成任务时,可以快速对比不同模型的生成效果,选择最优的模型进行图像生成。

· 多任务处理:在一个复杂的生成任务中,可能需要使用不同的模型来处理不同的部分。CR Select Model 节点可以帮助用户轻松切换模型。

· 模型调优:在模型调优和测试过程中,可以使用该节点切换不同的模型,观察不同设置对生成结果的影响。

CR Select Model 节点可以帮助你在 ComfyUI 中灵活地选择和切换生成模型,确保你能够使用最适合当前任务的模型,提高图像生成的效率和效果。

七、CR Combine Prompt节点

该节点是一个用于合并和处理多个文本提示的节点,这个节点允许用户将多个独立的文本提示结合起来,以生成更复杂和详细的图像描述。

12

参数:

part1 → 写入用于生成图像的prompt

part2 → 写入用于生成图像的prompt

part3 → 写入用于生成图像的prompt

part4 → 写入用于生成图像的prompt

separatpr → 定义合并多个prompt时,各个提示之间使用的分隔符

输出:

prompt → 输出合并后的提示词prompt

show_help → 激活帮助信息或指导(可不连接)

使用场景

· 详细描述生成:当需要生成一个具有多个特征或元素的图像时,可以将多个文本提示组合在一起,以提供更详细的描述。

· 风格混合:用户可以将描述不同风格的文本提示组合在一起,以生成融合多种风格的图像。

· 创意探索:通过组合不同的文本提示,可以生成具有创新性和独特性的图像,探索新的创作思路。

CR Combine Prompt 节点可以帮助你在 ComfyUI 中灵活地组合和处理多个文本提示,生成更加丰富和详细的图像描述,提升生成图像的质量和多样性。

八、CR prompt Text节点

该节点是一个用于输入和管理文本提示的节点,这个节点允许为生成模型提供文本描述,以指导图像生成过程。

13

参数:

prompt → 用户输入用于生成图像的文本提示

show_help → 激活帮助信息或指导(可不连接)

输出:

Prompt → 在文本编辑器里输入描述性的词语、关键词、短句或其他视觉元素

使用场景

· 图像描述:用户可以输入详细的文本描述,以生成符合特定描述的图像。例如,“a beautiful landscape with mountains and a river at sunset”。

· 风格指引:通过输入特定的风格描述,用户可以生成具有特定艺术风格的图像。例如,“in the style of Van Gogh”。

· 特定主题生成:用户可以输入特定主题的文本提示,以生成符合该主题的图像。例如,“a futuristic city with flying cars”。

CR Prompt Text 节点可以帮助你在 ComfyUI 中输入和管理文本提示,为生成模型提供详细的描述信息,以生成符合预期的图像。这使得图像生成过程更加直观和灵活,用户可以通过简单的文本输入来控制生成结果。

九、CR VAE Decode节点

该节点是一个用于解码变分自编码器(Variational Autoencoder, VAE)潜在空间表示的节点,它将潜在向量转换为图像,能够从潜在空间生成实际的图像内容。

14

输入:

samples → 接受生成图像数量样本数值

vae → 将处理后的样本集合传递给后面的节点

参数:

tiled → 是否将生成的图像样本以平铺的方式排列

circular → 控制图像样本边界处理方式

输出

IMAGE → 将解码后的图像输出连接到显示或保存节点

show_help → 激活帮助信息或指导(可不连接)

使用场景

· 图像生成:从随机或特定的潜在向量生成图像,用于图像生成任务。

· 图像重建:将图像编码为潜在向量后,再解码回原始图像,以验证编码器和解码器的性能。

· 风格迁移:通过调整潜在向量,实现图像风格的转换和编辑。

· 图像编辑:在潜在空间中进行操作(如插值、加噪声),再解码为图像,实现图像的编辑和增强。

CR VAE Decode 节点可以帮助你在 ComfyUI 中解码潜在空间表示,生成具有特定特征和内容的图像。这使得图像生成和编辑过程更加灵活和多样化,可以通过操控潜在向量实现不同的创意效果。

  1. Comfyroll Studio 基础工作流搭建

熟练使用以上节点,你就可以搭建有关Comfyroll Studio 的工作流了。

15

**孜孜以求,方能超越自我。坚持不懈,乃是成功关键。**

前言

因为本人天资愚钝,所以总喜欢将抽象化的事务具象化表达。对于各类眼花缭乱的树,只需要认知到它们只是一种数据结构,类似数组,切片,列表,映射等这些耳熟能详的词汇。对于一个数据结构而言,无非就是增删改查而已,既然各类树也是数据结构,它们就不能逃离增删改查的桎梏。

那么,为什么我们需要树这种数据结构呢,直接用数组不行吗,用切片不行吗?当然可以,只不过现实世界是缤纷杂乱的,而又没有一种万能药式的数据结构以应对千变万化的业务需求。所以,才会有各类树,而且一些“高级”数据结构是基于树形数据结构的,例如映射。

二叉树

在中文语境中,节点结点傻傻分不清楚,故后文以 node 代表 "结点",root node 代表根节点,child node 代表 “子节点”

二叉树是诸多树状结构的始祖,至于为什么不是三叉树,四叉树,或许是因为计算机只能数到二吧,哈哈,开个玩笑。二叉树很简单,每个 node 最多存在两个 child node,第一个节点称之为 root node。

二叉树具备着一些基本的数学性质,不过很简单,定义从
i
从 0 开始:


  • i
    层至多有
    2 i
    个 node;
  • 深度为 i 层二叉树至多有
    2 i+1 -1
    个 node。

二叉树的特殊类型

这里有兴趣的可以了解一下,不影响后文的阅读。二叉树根据 child node 的不同,衍生出了几种特殊类型:在一颗二叉树中,如果每个 node 都有 0 或 2 个 child node,则二叉树是
满二叉树
;定义从
i
从 0 开始,一棵深度为
i
,且仅有
2 i+1 −1
个 node 的二叉树,称为
完美二叉树
;若除最后一层外的其余层都是满的,并且最后一层要么是满的,要么在右边缺少连续若干 node,则此二叉树为
完全二叉树

二叉搜索树

二叉搜索树(Binary Search Tree),也叫二叉查找树,有序二叉树,排序二叉树(名字还挺多)。它是一种常用且特殊的二叉树,它具备一个特有的性质,left node(左结点)始终小于 parent node (父结点),right node 始终大于 parent node。

二叉搜索树的查找

  1. 二叉搜索树从 root node 开始,如果命中则返回;
  2. 否则,目标值比 node 小进入 left node;
  3. 比 node 大进入 right node;
  4. 如果左右都为空,则未命中。

二叉搜索树的遍历

二叉搜索树有不同的遍历方式,这里介绍常用的中序遍历方式:

  1. 先遍历左子树;
  2. 然后查找当前左子树的 parent node;
  3. 遍历右子树。

二叉搜索树的插入

  1. 二叉搜索树从 root node 开始,如果命中则不进行操作;
  2. 否则,目标值比 node 小进入 left node;
  3. 比 node 大进入 right node;
  4. 最终将值插入搜索停止的地方。

二叉搜索树的删除

二叉树的删除和查询基本一致,只要在命中时删除即可。

  1. 二叉搜索树从 root node 开始,如果命中则删除;
  2. 否则,目标值比 node 小进入 left node;
  3. 比 node 大进入 right node;
  4. 删除后使用该 node
    左子树最大值或者右子树最小值
    替代该 node。

自平衡二叉树

从上面的几张动图中我们知晓,二叉搜索树不同于线性结构,它可以大大降低查找,插入的时间复杂度。但在特殊情况下,二叉搜索树可能退化为线性结构,假如我们依次插入1,2,3,4,5:

此时,二叉搜索树退化为线性结构,效率重新变回遍历。于是,便出现了自平衡二叉树,例如 AVL 树,红黑树,替罪羊树等。但它们并不是本文重点,下面我要介绍的是另外一种很常见的自平衡二叉树:B树。

B树

B树和B-树是同一个概念。
B树相对于二叉树有两点最大的不同:

  • 每个 node 可以有不止一个数值
  • 每个 node 也可以有不止两个 child node

B树有两种类型 node:

  • internal node(内部结点):不仅仅存储数据,也具备 child node;
  • leaf node(叶子结点):仅存储数据,不具备 child node。

这两种 node 不同于前文所提的 root node 和 child node。root 和 child 是相对于阶层的概念,而 internal 和 leaf 是相对于性质的概念

一个简单的图例如下:

图中的蓝色方块是 internal node,绿色则是 leaf node。

B树有一些需要满足的性质,这里的抽象的逻辑有些烧脑,我会对照前面的图片来解释。设定一颗 m 阶的B树,
m = 3

设 internal node 的 child node 个数为
k

  1. 如果 internal node 是 root node,那么
    k = [2, m]
    ,比如上图的 8 有两个 child node(3|6, 10/12);
  2. 如果 internal node 不是 root node,那么
    k = [m/2, m]
    ,m/2 向上取整,比如上图的
    3|6
    有三个 child node;
  3. 如果 root node 的
    k
    为 0,那么 root node 是 leaf 类型的;
  4. 所有 leaf node 在同一层,上图最后一行的六个 node。

设任意 node 键值个数为
n

  1. 对于 internal node,
    n = k-1
    , 升序排序,满足
    k[i] < k[i+1]
    ,比如上图的三个 internal(8,3|6,10|12) 都满足此规律;
  2. 对于 leaf node,
    n = [0, m-1]
    ,同样升序排序,比如上图最后一个的六个 leaf,其键值最多为两个。

上述的概念有些抽象,但是这是理解B树关键的地方所在,后面在B树的插入讲解,会有更多具象的动图来解释这些概念。

B树的查找

B树的查找类似于二叉树:

  1. 从 root node 开始,如果目标值小于 root node,进入左子树,否则进入右子树;
  2. 遍历 child node 的多个键值;
  3. 如果匹配到键值,则返回;
  4. 如果不匹配,则根据目标值的范围选择对应的子树;
  5. 重复步骤2、3、4,直到匹配成功返回或者未找到。

假如我们要查找 11:

B树的遍历

B树的遍历方式类似二叉搜索树,不过因为B树一个 node 有多个键值和多个 child node,所以需要遍历每个左右子树和键值:

  1. 先遍历第一个左子树,也就是 parent node 第一个键值的左边;
  2. 然后查找当前 parent node 的第一个键值;
  3. 遍历第二个左子树,也就是 parent node 第二个键值的左边;
  4. 遍历完搜索的左子树,最后遍历当前 parent 的最右子树,即最后一个键值的右边。

B树的插入

插入前面的过程和查询一致,在插入后可能需要重整 node,以符合B树的性质,例如插入 16:

  1. 先查找到目标 node,也就是
    13|15
  2. 因为这是一颗 3 阶B树,所以 node 最多只能有两个键值,于是向上传递中间值 15;
  3. parent node 最多也只能有两个键值,于是继续向上传递中间值 12;
  4. 此时 root node 是 8|12,需要有三个 child node,于是 10|15 需要拆分,再向下进一步调整,至此,插入 16 完成。

B树的删除

删除是插入的逆操作,但是往往比插入更复杂,因为删除后经常需要重整 node:

  1. 先查找到目标 node,也就是
    16
  2. 删除 16,此时 15 child node 剩下一个,不符合条件,递归向上调整,一直到根节点;
  3. 直到所有的条件都满足后,删除 16 完成。