【“星瑞” O6 評測】 — CPU llama.cpp不同優化速度對比

在這里插入圖片描述

前言

隨著大模型應用場景的不斷拓展,arm cpu 憑借其獨特優勢在大模型推理領域的重要性日益凸顯。它在性能、功耗、架構適配等多方面發揮關鍵作用,推動大模型在不同場景落地

1. Kleidi AI 簡介

Arm Kleidi 成為解決這些挑戰的理想方案,它能夠為運行在 Arm CPU 上的所有 AI 推理工作負載提供無縫的性能優化。KleidiAI 是一套輕量級且高性能開源的 Arm 例程,專為 AI 加速而設計。Arm 的 KleidiAI 庫,提供了針對 sme、i8mm 和點積加速等硬件功能優化的矩陣乘法內核,目前已被集成到最新版本的主流端側 AI 框架中,包括 ExecuTorch、Llama.cpp、LiteRT (通過XNNPACK)和 MediaPipe,能讓數百萬名開發者無需進行額外操作,即可自動獲取 AI 性能的顯著提升。

這里我們對比同一個模型,CPU編譯時不同優化選項帶來的提升

2. 依賴安裝

sudo apt install cmake libcurl4-openssl-dev

下載代碼

git clone https://github.com/ggml-org/llama.cpp.git## 切換到我測試的分支(可選)
git checkout b5195

3. 編譯時不同優化選項實測

3.1 不開啟任何優化

cmake -B build
cmake --build build --config Release -j

3.2 下載/轉換/量化模型

https://www.modelscope.cn/models/Qwen/Qwen2.5-3B-Instruct/files下載模型

轉換

pip install -r requirements/requirements-convert_hf_to_gguf.txt
python convert_hf_to_gguf.py /home/radxa/.cache/modelscope/hub/models/Qwen/Qwen2.5-3B-Instruct

量化

可以將模型的權重系數量化成Q4_0

./build/bin/llama-quantize /home/radxa/.cache/modelscope/hub/models/Qwen/Qwen2.5-3B-Instruct/Qwen2.5-3B-Instruct-F16.gguf asserts/Qwen2.5-3B-Instruct-Q4_0.gguf Q4_0

驗證模型正確性

taskset -c 0,5,6,7,8,9,10,11 ./build/bin/llama-cli -m asserts/Qwen2.5-3B-Instruct-Q4_0.gguf -c 4096 -t 8 --conversation

打印信息

> hello
Hello! How can I assist you today? Do you have any questions or topics you'd like to discuss?> 
llama_perf_sampler_print:    sampling time =       2.79 ms /    32 runs   (    0.09 ms per token, 11477.76 tokens per second)
llama_perf_context_print:        load time =     498.94 ms
llama_perf_context_print: prompt eval time =     592.82 ms /     9 tokens (   65.87 ms per token,    15.18 tokens per second)
llama_perf_context_print:        eval time =    1711.00 ms /    22 runs   (   77.77 ms per token,    12.86 tokens per second)
llama_perf_context_print:       total time =    6498.13 ms /    31 tokens
Interrupted by user

3.3 不開啟任何優化的benchmark

taskset -c 0,5,6,7,8,9,10,11 ./build/bin/llama-bench -m asserts/Qwen2.5-3B-Instruct-Q4_0.gguf -p 128 -n 128 -t 8

結果

modelsizeparamsbackendthreadstestt/s
qwen2 3B Q4_01.69 GiB3.09 BCPU8pp12817.16 ± 0.08
qwen2 3B Q4_01.69 GiB3.09 BCPU8tg12812.85 ± 0.09

3.4 開啟avmv9優化

編譯

cmake -B build_armv9 -DCMAKE_CXX_FLAGS="-march=armv9-a" -DCMAKE_C_FLAGS="-march=armv9-a"
cmake --build build_armv9 --config Release -j

benchmark命令: taskset -c 0,5,6,7,8,9,10,11 ./build_armv9/bin/llama-bench -m asserts/Qwen2.5-3B-Instruct-Q4_0.gguf -p 128 -n 128 -t 8

結果

modelsizeparamsbackendthreadstestt/s
qwen2 3B Q4_01.69 GiB3.09 BCPU8pp12884.39 ± 0.80
qwen2 3B Q4_01.69 GiB3.09 BCPU8tg12818.76 ± 0.22

3.5 開啟kleidiai優化

kleidiai已經集成到llama.cpp的后端,只需要編譯時給定正確的選項就行。

官方給的編譯,我有報錯

cmake -B build_kle -DGGML_CPU_KLEIDIAI=ON
cmake --build build_kle --config Release -j

報錯:

/home/radxa/1_AI_models/llama.cpp/ggml/src/ggml-cpu/kleidiai/kernels.cpp:22:30: error: zero-size array ‘gemm_gemv_kernels’22 | static ggml_kleidiai_kernels gemm_gemv_kernels[] = {|                              ^~~~~~~~~~~~~~~~~
gmake[2]: *** [ggml/src/CMakeFiles/ggml-cpu.dir/build.make:272: ggml/src/CMakeFiles/ggml-cpu.dir/ggml-cpu/kleidiai/kernels.cpp.o] Error 1
gmake[2]: *** Waiting for unfinished jobs....

于是改用clang++編譯器,

## 安裝依賴
sudo apt install clang libomp-dev## 編譯
cmake -B build_kle -DGGML_CPU_KLEIDIAI=ON -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++
cmake --build build_kle --config Release -j

benchmark命令: taskset -c 0,5,6,7,8,9,10,11 ./build_kle/bin/llama-bench -m asserts/Qwen2.5-3B-Instruct-Q4_0.gguf -p 128 -n 128 -t 8

結果

modelsizeparamsbackendthreadstestt/s
qwen2 3B Q4_01.69 GiB3.09 BCPU8pp128129.53 ± 6.59
qwen2 3B Q4_01.69 GiB3.09 BCPU8tg12816.25 ± 0.18

打印中有load_tensors: CPU_KLEIDIAI model buffer size = 1488.38 MiBKLEIDIAI = 1表明編譯選項正確打開。
全部的打印信息。

build: 5195 (2d451c80) with cc (Debian 12.2.0-14) 12.2.0 for aarch64-linux-gnu
main: llama backend init
main: load the model and apply lora adapter, if any
llama_model_loader: loaded meta data with 35 key-value pairs and 434 tensors from asserts/Qwen2.5-3B-Instruct-Q4_0.gguf (version GGUF V3 (latest))
llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output.
llama_model_loader: - kv   0:                       general.architecture str              = qwen2
llama_model_loader: - kv   1:                               general.type str              = model
llama_model_loader: - kv   2:                               general.name str              = Qwen2.5 3B Instruct
llama_model_loader: - kv   3:                           general.finetune str              = Instruct
llama_model_loader: - kv   4:                           general.basename str              = Qwen2.5
llama_model_loader: - kv   5:                         general.size_label str              = 3B
llama_model_loader: - kv   6:                            general.license str              = other
llama_model_loader: - kv   7:                       general.license.name str              = qwen-research
llama_model_loader: - kv   8:                       general.license.link str              = https://huggingface.co/Qwen/Qwen2.5-3...
llama_model_loader: - kv   9:                   general.base_model.count u32              = 1
llama_model_loader: - kv  10:                  general.base_model.0.name str              = Qwen2.5 3B
llama_model_loader: - kv  11:          general.base_model.0.organization str              = Qwen
llama_model_loader: - kv  12:              general.base_model.0.repo_url str              = https://huggingface.co/Qwen/Qwen2.5-3B
llama_model_loader: - kv  13:                               general.tags arr[str,2]       = ["chat", "text-generation"]
llama_model_loader: - kv  14:                          general.languages arr[str,1]       = ["en"]
llama_model_loader: - kv  15:                          qwen2.block_count u32              = 36
llama_model_loader: - kv  16:                       qwen2.context_length u32              = 32768
llama_model_loader: - kv  17:                     qwen2.embedding_length u32              = 2048
llama_model_loader: - kv  18:                  qwen2.feed_forward_length u32              = 11008
llama_model_loader: - kv  19:                 qwen2.attention.head_count u32              = 16
llama_model_loader: - kv  20:              qwen2.attention.head_count_kv u32              = 2
llama_model_loader: - kv  21:                       qwen2.rope.freq_base f32              = 1000000.000000
llama_model_loader: - kv  22:     qwen2.attention.layer_norm_rms_epsilon f32              = 0.000001
llama_model_loader: - kv  23:                       tokenizer.ggml.model str              = gpt2
llama_model_loader: - kv  24:                         tokenizer.ggml.pre str              = qwen2
llama_model_loader: - kv  25:                      tokenizer.ggml.tokens arr[str,151936]  = ["!", "\"", "#", "$", "%", "&", "'", ...
llama_model_loader: - kv  26:                  tokenizer.ggml.token_type arr[i32,151936]  = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
llama_model_loader: - kv  27:                      tokenizer.ggml.merges arr[str,151387]  = ["? ?", "?? ??", "i n", "? t",...
llama_model_loader: - kv  28:                tokenizer.ggml.eos_token_id u32              = 151645
llama_model_loader: - kv  29:            tokenizer.ggml.padding_token_id u32              = 151643
llama_model_loader: - kv  30:                tokenizer.ggml.bos_token_id u32              = 151643
llama_model_loader: - kv  31:               tokenizer.ggml.add_bos_token bool             = false
llama_model_loader: - kv  32:                    tokenizer.chat_template str              = {%- if tools %}\n    {{- '<|im_start|>...
llama_model_loader: - kv  33:               general.quantization_version u32              = 2
llama_model_loader: - kv  34:                          general.file_type u32              = 2
llama_model_loader: - type  f32:  181 tensors
llama_model_loader: - type q4_0:  252 tensors
llama_model_loader: - type q6_K:    1 tensors
print_info: file format = GGUF V3 (latest)
print_info: file type   = Q4_0
print_info: file size   = 1.69 GiB (4.71 BPW) 
load: special tokens cache size = 22
load: token to piece cache size = 0.9310 MB
print_info: arch             = qwen2
print_info: vocab_only       = 0
print_info: n_ctx_train      = 32768
print_info: n_embd           = 2048
print_info: n_layer          = 36
print_info: n_head           = 16
print_info: n_head_kv        = 2
print_info: n_rot            = 128
print_info: n_swa            = 0
print_info: n_swa_pattern    = 1
print_info: n_embd_head_k    = 128
print_info: n_embd_head_v    = 128
print_info: n_gqa            = 8
print_info: n_embd_k_gqa     = 256
print_info: n_embd_v_gqa     = 256
print_info: f_norm_eps       = 0.0e+00
print_info: f_norm_rms_eps   = 1.0e-06
print_info: f_clamp_kqv      = 0.0e+00
print_info: f_max_alibi_bias = 0.0e+00
print_info: f_logit_scale    = 0.0e+00
print_info: f_attn_scale     = 0.0e+00
print_info: n_ff             = 11008
print_info: n_expert         = 0
print_info: n_expert_used    = 0
print_info: causal attn      = 1
print_info: pooling type     = 0
print_info: rope type        = 2
print_info: rope scaling     = linear
print_info: freq_base_train  = 1000000.0
print_info: freq_scale_train = 1
print_info: n_ctx_orig_yarn  = 32768
print_info: rope_finetuned   = unknown
print_info: ssm_d_conv       = 0
print_info: ssm_d_inner      = 0
print_info: ssm_d_state      = 0
print_info: ssm_dt_rank      = 0
print_info: ssm_dt_b_c_rms   = 0
print_info: model type       = 3B
print_info: model params     = 3.09 B
print_info: general.name     = Qwen2.5 3B Instruct
print_info: vocab type       = BPE
print_info: n_vocab          = 151936
print_info: n_merges         = 151387
print_info: BOS token        = 151643 '<|endoftext|>'
print_info: EOS token        = 151645 '<|im_end|>'
print_info: EOT token        = 151645 '<|im_end|>'
print_info: PAD token        = 151643 '<|endoftext|>'
print_info: LF token         = 198 '?'
print_info: FIM PRE token    = 151659 '<|fim_prefix|>'
print_info: FIM SUF token    = 151661 '<|fim_suffix|>'
print_info: FIM MID token    = 151660 '<|fim_middle|>'
print_info: FIM PAD token    = 151662 '<|fim_pad|>'
print_info: FIM REP token    = 151663 '<|repo_name|>'
print_info: FIM SEP token    = 151664 '<|file_sep|>'
print_info: EOG token        = 151643 '<|endoftext|>'
print_info: EOG token        = 151645 '<|im_end|>'
print_info: EOG token        = 151662 '<|fim_pad|>'
print_info: EOG token        = 151663 '<|repo_name|>'
print_info: EOG token        = 151664 '<|file_sep|>'
print_info: max token length = 256
load_tensors: loading model tensors, this can take a while... (mmap = true)
load_tensors:   CPU_Mapped model buffer size =  1720.63 MiB
load_tensors: CPU_KLEIDIAI model buffer size =  1488.38 MiB
.......................................................................................
llama_context: constructing llama_context
llama_context: n_seq_max     = 1
llama_context: n_ctx         = 4096
llama_context: n_ctx_per_seq = 4096
llama_context: n_batch       = 2048
llama_context: n_ubatch      = 512
llama_context: causal_attn   = 1
llama_context: flash_attn    = 0
llama_context: freq_base     = 1000000.0
llama_context: freq_scale    = 1
llama_context: n_ctx_per_seq (4096) < n_ctx_train (32768) -- the full capacity of the model will not be utilized
llama_context:        CPU  output buffer size =     0.58 MiB
init: kv_size = 4096, offload = 1, type_k = 'f16', type_v = 'f16', n_layer = 36, can_shift = 1
init:        CPU KV buffer size =   144.00 MiB
llama_context: KV self size  =  144.00 MiB, K (f16):   72.00 MiB, V (f16):   72.00 MiB
llama_context:        CPU compute buffer size =   300.75 MiB
llama_context: graph nodes  = 1338
llama_context: graph splits = 1
common_init_from_params: setting dry_penalty_last_n to ctx_size = 4096
common_init_from_params: warming up the model with an empty run - please wait ... (--no-warmup to disable)
main: llama threadpool init, n_threads = 8
main: chat template example:
<|im_start|>system
You are a helpful assistant<|im_end|>
<|im_start|>user
Hello<|im_end|>
<|im_start|>assistant
Hi there<|im_end|>
<|im_start|>user
How are you?<|im_end|>
<|im_start|>assistantsystem_info: n_threads = 8 (n_threads_batch = 8) / 12 | CPU : NEON = 1 | ARM_FMA = 1 | FP16_VA = 1 | MATMUL_INT8 = 1 | SVE = 1 | DOTPROD = 1 | SVE_CNT = 16 | OPENMP = 1 | KLEIDIAI = 1 | AARCH64_REPACK = 1 | main: interactive mode on.
sampler seed: 3948005486
sampler params: repeat_last_n = 64, repeat_penalty = 1.000, frequency_penalty = 0.000, presence_penalty = 0.000dry_multiplier = 0.000, dry_base = 1.750, dry_allowed_length = 2, dry_penalty_last_n = 4096top_k = 40, top_p = 0.950, min_p = 0.050, xtc_probability = 0.000, xtc_threshold = 0.100, typical_p = 1.000, top_n_sigma = -1.000, temp = 0.800mirostat = 0, mirostat_lr = 0.100, mirostat_ent = 5.000
sampler chain: logits -> logit-bias -> penalties -> dry -> top-k -> typical -> top-p -> min-p -> xtc -> temp-ext -> dist 
generate: n_ctx = 4096, n_batch = 2048, n_predict = -1, n_keep = 0== Running in interactive mode. ==- Press Ctrl+C to interject at any time.- Press Return to return control to the AI.- To return control without starting a new line, end your input with '/'.- If you want to submit another line, end your input with '\'.- Not using system message. To change it, set a different value via -sys PROMPT

問題
但是這樣編譯出來的可執行程序,執行測試的時候,模型效果是有問題,還需要排查。

./build_kle/bin/llama-cli -m asserts/Qwen2.5-3B-Instruct-Q4_0.gguf -c 4096 -t 8 --conversation## 打印
> hello
共和國owan続きMAR composition composition分 mutationorphAug AovOransition""""""""""" "" "" "amyamy.tom Entriesreta_suffix"衛生ventions警MessageBox

4.總結

同樣的硬件,同樣的模型,從上面的評測可以看到開啟了kleidiai相較于armv9在prefill階段提升了54.49%, decode階段略有下降13.37。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903974.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903974.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903974.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

wireshark抓包也能被篡改?

wireshark本身并不能修改數據包&#xff0c;但是tcprewrite 可以修改數據包&#xff0c;然后通過tcpreplay 進行重放&#xff0c;這個時候wireshark抓的包&#xff0c;就是被篡改后的pcap包了。 ailx10 網絡安全優秀回答者 互聯網行業 安全攻防員 去咨詢 步驟一&#xff1a…

使用PyTorch進行熱狗圖像分類模型微調

本教程將演示如何使用PyTorch框架對預訓練模型進行微調&#xff0c;實現熱狗與非熱狗圖像的分類任務。我們將從數據準備開始&#xff0c;逐步完成數據加載、可視化等關鍵步驟。 1. 環境配置與庫導入 %matplotlib inline import os import torch from torch import nn from d2l…

內容中臺與企業內容管理核心差異剖析

功能定位與架構設計差異 在企業數字化進程中&#xff0c;內容中臺與企業內容管理&#xff08;ECM&#xff09;的核心差異首先體現在功能定位層面。傳統ECM系統以文檔存儲、版本控制及權限管理為核心&#xff0c;主要服務于企業內部知識庫的靜態管理需求&#xff0c;例如通過Ba…

使用PyMongo連接MongoDB的基本操作

MongoDB是由C語言編寫的非關系型數據庫&#xff0c;是一個基于分布式文件存儲的開源數據庫系統&#xff0c;其內容存儲形式類似JSON對象&#xff0c;它的字段值可以包含其他文檔、數組及文檔數組。在這一節中&#xff0c;我們就來回顧Python 3下MongoDB的存儲操作。 常用命令:…

第 12 屆藍橋杯 C++ 青少組中 / 高級組省賽 2021 年真題

一、選擇題 第 1 題 題目&#xff1a;下列符號中哪個在 C 中表示行注釋 ( )。 A. ! B. # C. ] D. // 正確答案&#xff1a;D 答案解析&#xff1a; 在 C 中&#xff0c;//用于單行注釋&#xff08;行注釋&#xff09;&#xff0c;從//開始到行末的內容會被編譯器忽略。選項 A…

【python】【UV】一篇文章學完新一代 Python 環境與包管理器使用指南

&#x1f40d; UV&#xff1a;新一代 Python 環境與包管理器使用指南 一、UV 是什么&#xff1f; UV 是由 Astral 團隊開發的高性能 Python 環境管理器&#xff0c;旨在統一替代 pyenv、pip、venv、pip-tools、pipenv 等工具。 1.1 UV 的主要功能 &#x1f680; 極速包安裝&…

前端性能優化2:結合HTTPS與最佳實踐,全面優化你的網站性能

點亮極速體驗&#xff1a;結合HTTPS與最佳實踐&#xff0c;為你詳解網站性能優化的道與術 在如今這個信息爆炸、用戶耐心極其有限的數字時代&#xff0c;網站的性能早已不是一個可選項&#xff0c;而是關乎生存和發展的核心競爭力。一個遲緩的網站&#xff0c;無異于在數字世界…

JavaWeb:vueaxios

一、簡介 什么是vue? 快速入門 <!-- 3.準備視圖元素 --><div id"app"><!-- 6.數據渲染 --><h1>{{ msg }}</h1></div><script type"module">// 1.引入vueimport { createApp, ref } from https://unpkg.com/vu…

Tauri聯合Vue開發中Vuex與Pinia關系及前景分析

在 TauriVue 的開發場景中&#xff0c;Vuex 和 Pinia 是兩種不同的狀態管理工具&#xff0c;它們的關系和前景可以從以下角度分析&#xff1a; 一、Vuex 與 Pinia 的關系 繼承與發展 Pinia 最初是作為 Vuex 5 的提案設計的&#xff0c;其目標是簡化 Vuex 的復雜性并更好地適配 …

Linux中的時間同步

一、時間同步服務擴展總結 1. 時間同步的重要性 多主機協作需求&#xff1a;在分布式系統、集群、微服務架構中&#xff0c;時間一致性是日志排序、事務順序、數據一致性的基礎。 安全協議依賴&#xff1a;TLS/SSL證書、Kerberos認證等依賴時間有效性&#xff0c;時間偏差可能…

【算法基礎】三指針排序算法 - JAVA

一、基礎概念 1.1 什么是三指針排序 三指針排序是一種特殊的分區排序算法&#xff0c;通過使用三個指針同時操作數組&#xff0c;將元素按照特定規則進行分類和排序。這種算法在處理包含有限種類值的數組時表現出色&#xff0c;最經典的應用是荷蘭國旗問題&#xff08;Dutch …

《操作系統真象還原》第十二章(2)——進一步完善內核

文章目錄 前言可變參數的原理實現系統調用write更新syscall.h更新syscall.c更新syscall-init.c 實現printf編寫stdio.h編寫stdio.c 第一次測試main.cmakefile結果截圖 完善printf修改main.c 結語 前言 上部分鏈接&#xff1a;《操作系統真象還原》第十二章&#xff08;1&#…

ICML2021 | DeiT | 訓練數據高效的圖像 Transformer 與基于注意力的蒸餾

Training data-efficient image transformers & distillation through attention 摘要-Abstract引言-Introduction相關工作-Related Work視覺Transformer&#xff1a;概述-Vision transformer: overview通過注意力機制蒸餾-Distillation through attention實驗-Experiments…

深度學習:AI 機器人時代

在科技飛速發展的當下&#xff0c;AI 機器人時代正以洶涌之勢席卷而來&#xff0c;而深度學習作為其核心驅動力&#xff0c;正重塑著我們生活與工作的方方面面。 從智能工廠的自動化生產&#xff0c;到家庭中貼心服務的智能助手&#xff0c;再到復雜環境下執行特殊任務的專業機…

《告別試錯式開發:TDD的精準質量鍛造術》

深度解鎖TDD&#xff1a;應用開發的創新密鑰 在應用開發的復雜版圖中&#xff0c;如何雕琢出高質量、高可靠性的應用&#xff0c;始終是開發者們不懈探索的核心命題。測試驅動開發&#xff08;TDD&#xff09;&#xff0c;作為一種顛覆性的開發理念與方法&#xff0c;正逐漸成…

應用層自定義協議序列與反序列化

目錄 一、網絡版計算器 二、網絡版本計算器實現 2.1源代碼 2.2測試結果 一、網絡版計算器 應用層定義的協議&#xff1a; 應用層進行網絡通信能否使用如下的協議進行通信呢&#xff1f; 在操作系統內核中是以這種協議進行通信的&#xff0c;但是在應用層禁止以這種協議進行…

Excel-CLI:終端中的輕量級Excel查看器

在數據驅動的今天&#xff0c;Excel 文件處理成為了我們日常工作中不可或缺的一部分。然而&#xff0c;頻繁地在圖形界面與命令行界面之間切換&#xff0c;不僅效率低下&#xff0c;而且容易出錯。現在&#xff0c;有了 Excel-CLI&#xff0c;一款運行在終端中的輕量級Excel查看…

百度后端開發一面

mutex, rwmutex 在Go語言中&#xff0c;Mutex&#xff08;互斥鎖&#xff09;和RWMutex&#xff08;讀寫鎖&#xff09;是用于管理并發訪問共享資源的核心工具。以下是它們的常見問題、使用場景及最佳實踐總結&#xff1a; 1. Mutex 與 RWMutex 的區別 Mutex: 互斥鎖&#xf…

STM32 IIC總線

目錄 IIC協議簡介 IIC總線系統結構 IIC總線物理層特點 IIC總線協議層 空閑狀態 應答信號 數據的有效性 數據傳輸 STM32的IIC特性及架構 STM32的IIC結構體 0.96寸OLED顯示屏 SSD1306框圖及引腳定義 4針腳I2C接口模塊原理圖 字節傳輸-I2C 執行邏輯框圖 命令表…

【unity游戲開發入門到精通——UGUI】整體控制一個UGUI面板的淡入淡出——CanvasGroup畫布組組件的使用

注意&#xff1a;考慮到UGUI的內容比較多&#xff0c;我將UGUI的內容分開&#xff0c;并全部整合放在【unity游戲開發——UGUI】專欄里&#xff0c;感興趣的小伙伴可以前往逐一查看學習。 文章目錄 前言CanvasGroup畫布組組件參數 實戰專欄推薦完結 前言 如果我們想要整體控制…