HuggingFace與自然語言處理(從框架學習到經典項目實踐)[ 01 API操作 ]

本教程適用與第一次接觸huggingface與相應框架和對nlp任務感興趣的朋友,該欄目目前更新總結如下:

  1. ??Tokenizer??:
    支持單句/雙句編碼,自動處理特殊符號和填充。
    批量編碼提升效率,適合訓練數據預處理。
  2. Datasets??:
    統一 API 處理多種格式數據(遠程/本地)。
    內置排序、分桶、拆分等功能,簡化數據準備流程。
  3. 應用場景??:
    文本分類、NER 等任務的數據預處理。
    快速實驗模型(如 BERT 微調)。
    通過 Hugging Face 工具,可高效完成 NLP 任務的 ??數據編碼 → 處理 → 訓練?? 全流程。

在這里插入圖片描述

Hugging Face 與自然語言處理(NLP)介紹

Hugging Face 是一家專注于 自然語言處理(NLP)機器學習(ML) 的公司,以其開源庫 Transformers 聞名。它提供了 預訓練模型(Pre-trained Models)、數據集(Datasets)、訓練工具(Trainer) 等,極大降低了 NLP 研究和應用的門檻。


1. Hugging Face 的核心產品

(1) Transformers 庫

? 核心功能:提供 BERT、GPT、T5、RoBERTa 等預訓練模型,支持 文本分類、翻譯、問答、文本生成 等任務。
? 特點
? PyTorch & TensorFlow 兼容:支持兩種主流深度學習框架。
? Pipeline API:幾行代碼即可完成 NLP 任務(如情感分析、命名實體識別)。
? 模型微調(Fine-tuning):可基于自己的數據調整預訓練模型。

示例代碼(情感分析)

from transformers import pipelineclassifier = pipeline("sentiment-analysis")
result = classifier("I love Hugging Face!")
print(result)  # [{'label': 'POSITIVE', 'score': 0.9998}]

(2) Datasets 庫

? 提供 10,000+ 數據集(如 GLUE、SQuAD、IMDb),支持快速加載和預處理。
? 特點
? 內存優化:流式加載大數據集(如 Wikipedia)。
? 數據預處理:內置 tokenization、批處理等功能。

示例代碼(加載 IMDb 數據集)

from datasets import load_datasetdataset = load_dataset("imdb")
print(dataset["train"][0])  # {'text': 'Great movie!', 'label': 1}

(3) Model Hub

? 托管 50,000+ 預訓練模型,涵蓋 NLP、CV、語音等領域。
? 支持社區共享:用戶可以上傳自己的模型供他人使用。

示例(下載 BERT 模型)

from transformers import BertModelmodel = BertModel.from_pretrained("bert-base-uncased")

(4) Spaces(模型部署)

? 免費托管 AI 應用(如聊天機器人、文本生成器)。
? 支持 Gradio、Streamlit 等交互式 UI。


2. 自然語言處理(NLP)簡介

NLP(Natural Language Processing)是 讓計算機理解、生成人類語言 的技術,應用廣泛:

(1) 主要任務

任務示例
文本分類情感分析(正面/負面)
命名實體識別(NER)識別 “Apple” 是公司還是水果
機器翻譯中英互譯
文本生成GPT-3 寫文章
問答系統Siri、ChatGPT
文本摘要自動生成新聞摘要

(2) 關鍵技術

? 詞嵌入(Word Embeddings)(如 Word2Vec、GloVe)
? Transformer 架構(如 BERT、GPT)
? 遷移學習(Transfer Learning):用預訓練模型微調下游任務。

(3) Hugging Face 在 NLP 中的作用

? 降低 NLP 門檻:無需從頭訓練模型,直接使用預訓練模型。
? 標準化流程:統一 API(如 AutoModelAutoTokenizer)。
? 社區驅動:研究者共享模型,推動 NLP 發展。


3. 典型 NLP 任務實戰

(1) 文本分類(情感分析)

from transformers import pipelineclassifier = pipeline("text-classification", model="distilbert-base-uncased-finetuned-sst-2-english")
result = classifier("Hugging Face is awesome!")
print(result)  # [{'label': 'POSITIVE', 'score': 0.9998}]

(2) 命名實體識別(NER)

ner = pipeline("ner", model="dbmdz/bert-large-cased-finetuned-conll03-english")
result = ner("Apple is headquartered in Cupertino.")
print(result)  # [{'entity': 'I-ORG', 'word': 'Apple'}, ...]

(3) 文本生成(GPT-2)

generator = pipeline("text-generation", model="gpt2")
result = generator("Once upon a time,", max_length=30)
print(result[0]["generated_text"])

4. 學習資源

? Hugging Face 官方課程:https://huggingface.co/course
? Transformers 文檔:https://huggingface.co/docs/transformers
? NLP 經典書籍:《Speech and Language Processing》(Jurafsky & Martin)


總結

方面Hugging Face 的貢獻
模型提供 BERT、GPT 等預訓練模型
數據托管大量 NLP 數據集
工具簡化訓練、推理、部署流程
社區推動開源 NLP 生態

Hugging Face 已成為 NLP 領域的 “GitHub”,無論是研究者還是開發者,都能快速構建 NLP 應用。🚀

下面專欄將一步一步學習huggingface框架的基礎操作:

編碼

新建編碼器

from transformers import BertTokenizer
tokenizers = BertTokenizer.from_pretrained(pretrained_model_name_or_path='google-bert/bert-base-chinese',cache_dir=None, // 默認緩存,也可以指定目錄force_download=False // 強制下載
)

編碼處理

encode() 一次編碼一個句子或者一對句子

# 基本編碼
out = tokenizers.encode_plus(text=sents[0],text_pair=sents[1],max_length=25,padding='max_length',truncation=True,return_tensors=None
)
print(out)
print(tokenizers.decode(token_ids=out['input_ids']))# 輸出
{'input_ids': [101, 872, 4991, 1762, 3441, 677, 4692, 7599, 3250, 102, 4692, 7599, 3250, 4638, 782, 1762, 3517, 677, 4692, 872, 102, 0, 0, 0, 0], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]}
[CLS] 你 站 在 橋 上 看 風 景 [SEP] 看 風 景 的 人 在 樓 上 看 你 [SEP] [PAD] [PAD] [PAD] [PAD]

(1)參數text和text_pair分別為兩個句子,如果只想編碼一個句子,則可讓text_pair傳None。

(2)參數truncation=True表明當句子長度大于max_length時,截斷句子。

(3)參數padding= 'max_length’表明當句子長度不足max_length時,在句子的后面補充PAD,直到max_length長度。

(4)參數add_special_tokens=True表明需要在句子中添加特殊符號。

(5)參數max_length=25定義了max_length的長度。

(6)參數return_tensors=None表明返回的數據類型為list格式,也可以賦值為tf、pt、np,分別表示TensorFlow、PyTorch、NumPy數據格式。

輸出解釋:

從輸出可以看出,編碼工具把兩個句子前后拼接在一起,中間使用[SEP]符號分隔,在整個句子的頭部添加符號[CLS],在整個句子的尾部添加符號[SEP],因為句子的長度不足max_length,所以補充了4個[PAD]。

進階編碼函數 encode_plus()

# 進階編碼函數
out = tokenizers.encode_plus(text=sents[2],text_pair=sents[3],max_length=25,padding='max_length',truncation=True,add_special_tokens=True,return_tensors=None,return_token_type_ids=True,return_attention_mask=True,return_special_tokens_mask=True,return_length=True,
)
# input_ids 編碼后的詞
# token_type_ids 第1個句子和特殊符號的位置是0,第2個句子的位置是1
# special_tokens_mask 特殊符號的位置是1,其他位置是0
# attention_mask PAD的位置是0,其他位置是1
# length 返回句子長度for key, value in out.items():print(key, value)print(tokenizers.decode(token_ids=out['input_ids'][0]))# 輸出 === === === === === === === ===
input_ids [101, 3209, 3299, 6163, 7652, 749, 872, 4638, 4970, 2094, 102, 872, 6163, 7652, 749, 1166, 782, 4638, 3457, 102, 0, 0, 0, 0, 0]
token_type_ids [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
special_tokens_mask [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
attention_mask [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
length 25
  • input_ids 編碼后的詞
  • token_type_ids 第1個句子和特殊符號的位置是0,第2個句子的位置是1
  • special_tokens_mask 特殊符號的位置是1,其他位置是0
  • attention_mask PAD的位置是0,其他位置是1
  • length 返回句子長度

批量編碼函數

print("# 批量編碼函數 ===============")
# 批量編碼函數
batch_sents = [sents[0], sents[1], sents[2], sents[3]]
out = tokenizers.batch_encode_plus(batch_text_or_text_pairs=batch_sents,max_length=25,padding='max_length',truncation=True,add_special_tokens=True,return_tensors=None,return_token_type_ids=True,return_attention_mask=True,return_special_tokens_mask=True,return_length=True,
)
print(out)
for key, value in out.items():print(key, value)
print(tokenizers.decode(token_ids=out['input_ids'][0]))## 輸出 ========
input_ids [[101, 872, 4991, 1762, 3441, 677, 4692, 7599, 3250, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [101, 4692, 7599, 3250, 4638, 782, 1762, 3517, 677, 4692, 872, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [101, 3209, 3299, 6163, 7652, 749, 872, 4638, 4970, 2094, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [101, 872, 6163, 7652, 749, 1166, 782, 4638, 3457, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
token_type_ids [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
special_tokens_mask [[1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
length [10, 12, 11, 10]
attention_mask [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
[CLS] 你 站 在 橋 上 看 風 景 [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]

可以看到,這里的輸出都是二維的list了,表明這是一個批量的編碼。這個函數在后續章節中會多次用到。

字典

獲取字典

添加字典元素

from transformers import BertTokenizer
tokenizers = BertTokenizer.from_pretrained(pretrained_model_name_or_path='google-bert/bert-base-chinese',cache_dir=None,force_download=False
)# 查看字典
vocab = tokenizers.get_vocab()
print(vocab)
print(type(vocab))
print(len(vocab))
print('沐浴' in vocab)# 添加字典元素
print("添加字典元素========")
tokenizers.add_tokens(new_tokens=["明月","裝飾","窗子"])
tokenizers.add_special_tokens({'eos_token': '[EOS]'})
out = tokenizers.encode(text='明月裝飾了你的窗子[EOS]'
, text_pair=None ,add_special_tokens=True,truncation=True,padding="max_length",max_length=10,return_tensors=None)
print(out)
print(tokenizers.decode(out))# 輸出 ============
添加字典元素========
[101, 21128, 21129, 749, 872, 4638, 21130, 21131, 102, 0]
[CLS] 明月 裝飾 了 你 的 窗子 [EOS] [SEP] [PAD]

可以看到,“明月”已經被識別為一個詞,而不是兩個詞,新的特殊符號[EOS]也被正確識別。

數據集工具

在以往的自然語言處理任務中會花費大量的時間在數據處理上,針對不同的數據集往往需要不同的處理過程,各個數據集的格式差異大,處理起來復雜又容易出錯。針對以上問題,HuggingFace提供了統一的數據集處理工具,讓開發者在處理各種不同的數據集時可以通過統一的API處理,大大降低了數據處理的工作量。

遠程加載并且保存

# 加載數據集
from datasets import load_dataset,load_from_disk
dataset = load_dataset(path="lansinuote/ChnSentiCorp",trust_remote_code=True)
print(dataset)# 加載數據集并且保存
load_dataset(path="glue",name="sst2",split='train')
dataset.save_to_disk(dataset_dict_path='./data/ChnSentiCorp')

磁盤加載


# 從磁盤加載數據集并且查看
dataset = load_from_disk(dataset_path="./data/ChnSentiCorp")
print(dataset)
dataset = dataset["train"]
print(dataset)
for i in [12, 17, 20, 26, 56]: print(dataset[i])## 輸出 =================
DatasetDict({train: Dataset({features: ['text', 'label'],num_rows: 9600})validation: Dataset({features: ['text', 'label'],num_rows: 1200})test: Dataset({features: ['text', 'label'],num_rows: 1200})
})
Dataset({features: ['text', 'label'],num_rows: 9600
})
{'text': '輕便,方便攜帶,性能也不錯,能滿足平時的工作需要,對出差人員來說非常不錯', 'label': 1}
{'text': '很好的地理位置,一蹋糊涂的服務,蕭條的酒店。', 'label': 0}
{'text': '非常不錯,服務很好,位于市中心區,交通方便,不過價格也高!', 'label': 1}
{'text': '跟住招待所沒什么太大區別。 絕對不會再住第2次的酒店!', 'label': 0}
{'text': '價格太高,性價比不夠好。我覺得今后還是去其他酒店比較好。', 'label': 0}

數據集的分析

數據排序

# 數據排序
print(dataset['label'][:10])
# 讓數據按照label排序
sorted_dataset = dataset.sort("label")
print(sorted_dataset['label'][:10])
print(sorted_dataset['label'][-10:])
# “和sort()函數相對應,可以使用shuffle()函數再次打亂數據,”
shuffled_dataset = dataset.shuffle()
print(shuffled_dataset["label"][:10])

數據抽樣

# 數據集的抽樣 抽樣后形成新的數據子集
print(shuffled_dataset.select([1,2,3,4,99]))
for i in range(5): print(shuffled_dataset[i])

{‘text’: ‘指紋機。價格略高。散熱有待加強。播放720P高清電影還是有點卡。略重。’, ‘label’: 0}

{‘text’: ‘輕便、小巧、配置不錯! 送貨速度快,當天下午四點多下單,次日上午十點到貨。’, ‘label’: 1}

{‘text’: ‘我借給一個朋友看的時候,問她看的時候會不會想哭,她說會。我也是一樣的感受。為什么又說不上。只是感覺程然描繪得很細膩,很真實。禪學,我是看了這本書才有所了解,因為當時心很亂,需要這類書的安慰。看來以后,在當當網等了很久才終于沒缺貨,終于買到了。捧在手里,感動和悲傷同在。但是這本書真的很適合我們去讀。在這紛亂的世界里,能有這本書作伴,謝謝程然了!’, ‘label’: 1}

{‘text’: ‘穿越的書我買了好幾套了 在當當網上看見《蔓蔓清蘿》的評論還多好了 就買來看看 看了文章后真的讓人有些失望 寫得不是那么生動 感覺太簡單化了 反而我比較喜歡《步步驚心》這本書 也是穿越的 o(∩_∩)o…’, ‘label’: 0}

升級版數據集拆分

# 訓練集測試集拆分
train_dataset,test_dataset = dataset.train_test_split(test_size=0.2).values()
print(train_dataset)
print(test_dataset)# 輸出 === === === ===
Dataset({features: ['text', 'label'],num_rows: 7680
})
Dataset({features: ['text', 'label'],num_rows: 1920
})

數據分桶可以使用shared ()函數把數據均勻地分為n部分,代碼如下:

dataset.shard(num_shards=4, index=0)

(1)參數num_shards表明要把數據均勻地分為幾部分,例子中分為4部分。

(2)參數index表明要取出第幾份數據,例子中為取出第0份。

運行結果如下:Dataset({features: ['text', 'label'],num_rows: 2400})

過濾數據

字段 操作


# 字段重命名
dataset_Sentence_label = dataset.rename_column("text","sentence")
print(dataset_Sentence_label)# 字段刪除
dataset.remove_columns("label")
print(dataset)

映射與數據格式


# 映射函數map
def add_prefix(example):example["sentence"] = "prefix:" + example["sentence"]return examplemaped_dataset = dataset_Sentence_label.map(add_prefix)
print(maped_dataset['sentence'][:10])
print(maped_dataset)# 設置數據格式
maped_dataset = maped_dataset.set_format(type="pandas",columns=['label'],output_all_columns=True)
print(maped_dataset)

數據導出

導出為 csv 文件

# 數據導出
dataset.to_csv("./data_csv/ChnSentiCorp.csv")
csv_dataset = load_dataset("csv",data_files="./data_csv/ChnSentiCorp.csv",split='train')
print(csv_dataset)
print(csv_dataset[:10])

導出為 json

dataset=load_dataset(path='seamew/ChnSentiCorp', split='train')
dataset.to_json(path_or_buf='./data/ChnSentiCorp.json')
#加載JSON格式數據
json_dataset=load_dataset(path='json',data_files='./data/ChnSentiCorp.json',split='train')
print(json_dataset[20])

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

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

相關文章

【LeetCode 42】接雨水(單調棧、DP、雙指針)

題面: 思路: 能接雨水的點,必然是比兩邊都低(小)的點。有兩種思路,一種是直接計算每個點的最大貢獻(也就是每個點在縱向上最多能接多少水),另一種就是計算每個點在橫向上…

【嵌入式開發-USB】

嵌入式開發-USB ■ USB簡介 ■ USB簡介

Visual Studio 項目轉Qt項目

1. 先確保qmake 和 minGW (g) 路徑都在系統變量內;或者通過WinR -> cmd 來檢測, 如果能夠 顯示qmake 的信息 , g 的信息 , 就說明設置環境變量成功。 2. 打開項目文件夾,在這里打開cmd, 換…

總線通信篇:I2C、SPI、CAN 的底層結構與多機通信設計

本文為嵌入式通信協議系列第三章,深入剖析 MCU 世界中的三大總線協議 —— I2C、SPI 和 CAN。 這些總線協議廣泛應用于傳感器數據采集、Flash 存儲、外設擴展、汽車電子、工業設備控制等領域,是嵌入式開發不可或缺的通信骨架。 ?? 一、總線通信的基本概念 1.1 什么是總線?…

sherpa:介紹

更多內容:XiaoJ的知識星球 目錄 1. sherpa 介紹 1. sherpa 介紹 sherpa是 Next-gen Kaldi 項目的部署框架。 sherpa 支持在各種平臺上部署與語音相關的預訓練模型,并提供多種語言綁定。 目前,sherpa 擁有以下子項目: k2-fsa/sh…

77.組合問題

主函數 combine def combine(self, n: int, k: int) -> List[List[int]]:result [] # 存放所有有效的組合self.backtracking(n, k, 1, [], result) # 從數字1開始搜索return result 作用:初始化并啟動回溯過程。參數: n4:數字范圍是1…

Oracle免費認證來襲

1、Oracle Cloud Infrastructure 2025 Foundations Associate” 🔗 考證地址:https://mylearn.oracle.com/ou/exam-unproctored/oracle-cloud-infrastructure-2025-foundations-associate-1z0-1085-25/148056/241954 2、Oracle Cloud Infrastructure 2…

【Unet++】

這是一篇關于語義分割U-net及其變體網絡結構的介紹性文章,主要介紹了U-net、U-net以及U-net的基本結構、特點和應用。 以下是對這些核心內容的簡要概述: 1. 語義分割U-net概述: - 基本結構:U-net是一種編碼解碼結構的網絡,起初…

git可視化工具Fork軟件的詳細使用教程

Fork是一款流行的Git圖形化客戶端,適用于Windows和macOS平臺。使用起來確實很方便,唯一的缺陷就是正版需要付費使用! Fork 安裝 官網下載地址:Fork官網地址https://git-fork.com/ 支持 macOS 和 Windows。 安裝完成后&#xff…

【JMeter技巧】GET請求如何傳遞Body參數?版本兼容性詳解場景需求

在實際接口測試中,有時會遇到特殊需求:需要給GET請求傳遞Body參數。但JMeter默認配置下,GET請求的Body數據會被自動忽略。本文將介紹如何通過配置解決這個問題。 配置步驟 1. 版本要求(重要!) JMeter ≥ …

HTML5好看的水果蔬菜在線商城網站源碼系列模板9

文章目錄 1.設計來源1.1 主界面1.2 商品界面1.3 購物車界面1.4 心愿列表界面1.5 商品信息界面1.6 博客界面1.7 關于我們界面1.8 聯系我們界面1.9 常見問題界面1.10 登錄界面 2.效果和源碼2.1 動態效果2.2 源代碼 源碼下載萬套模板,程序開發,在線開發&…

es 里的Filesystem Cache 理解

文章目錄 背景問題1,Filesystem Cache 里放的是啥問題2,哪些查詢它們會受益于文件系統緩存問題3 查詢分析 背景 對于es 優化來說常常看到會有一條結論給,給 JVM Heap 最多不超過物理內存的 50%,且不要超過 31GB(避免壓…

存儲器:DDR和獨立顯卡的GDDR有什么區別?

本文來簡要對比DDR(Double Data Rate SDRAM)和GDDR(Graphics Double Data Rate SDRAM)的區別,重點說明它們在設計、性能和應用上的差異: 1. 設計目標與架構 DDR:通用型DRAM,設計為…

【Electron】electron-vue 借助 element-ui UI 庫助力桌面應用開發

前面文章我們講過 electron 讓可以用 HTML、JS、CSS 開發桌面應用程序。而 electron-vue 是一個結合了 electron 與 vue 的套件。這樣我們就能方便地使用 vue 快速開發桌面應用。但是,vue 只是在 js 這層面做了大量的便捷的操作。對 UI 并未過多涉及。此時如果您在開…

Linux/AndroidOS中進程間的通信線程間的同步 - 消息隊列

本文介紹消息隊列,它允許進程之間以消息的形式交換數據。數據的交換單位是整個消息。 POSIX 消息隊列是引用計數的。只有當所有當前使用隊列的進程都關閉了隊列之后才會對隊列進行標記以便刪除。POSIX 消息有一個關聯的優先級,并且消息之間是嚴格按照優…

深入理解進程與線程、進程池與線程池:企業級開發實戰指南

簡介 并發編程是現代軟件開發的核心能力,而進程與線程、進程池與線程池是實現高效并發的關鍵技術。 本文將從基礎概念出發,深入解析它們的工作原理、優勢及適用場景,并提供Python、Java、C#等主流語言的實戰代碼,幫助開發者掌握企業級并發編程的最佳實踐。 一、進程與線程…

解鎖 LLM 推理速度:深入 FlashAttention 與 PagedAttention 的原理與實踐

寫在前面 大型語言模型 (LLM) 已經滲透到我們數字生活的方方面面,從智能問答、內容創作到代碼輔助,其能力令人驚嘆。然而,驅動這些強大模型的背后,是對計算資源(尤其是 GPU)的巨大需求。在模型推理 (Inference) 階段,即模型實際對外提供服務的階段,速度 (Latency) 和吞…

Go使用Gin寫一個對MySQL的增刪改查服務

首先用SQL創建一個包含id、name屬性的users表 create table users (id int auto_incrementprimary key,name varchar(255) null );查詢所有用戶信息: func queryData(db *sql.DB, w http.ResponseWriter) {rows, err : db.Query("SELECT * FROM users"…

鍵盤彈起導致頁面上移

問題:聊天頁面,如果輸入框設置了adjust-position屬性為true,會導致鍵盤彈起時,整個頁面上移,頂部導航欄也會跟著上移。 我想要的效果:鍵盤彈起時,頁面內容上移,頂部導航欄保持不動 …

機器視覺的手機FPC油墨絲印應用

在現代智能手機制造過程中,精密的組件裝配和質量控制是確保產品性能和用戶體驗的關鍵。其中,柔性印刷電路板(FPC)的油墨絲印工藝尤為關鍵,它不僅影響到電路板的美觀,更直接關系到電路的導電性能和可靠性。而…