[讀書清單] 關於 Staff Engineering 跟 Tech Management 相關書單

第一类,关于理解和成为(或选择不成为)Manager 的书籍:

《The Manager’s Path》(经典必读,即使不想当 Manager)

The Manager's Path

這個在 Safari Online 有,也有 audio Book 版本。 這本我也看完了,但是還沒寫心得分享。

《An Elegant Puzzle: Systems of Engineering Management》 from Amazon

image-20240130120333120

《Become an Effective Software Engineering Manager》(读的 Kindle 版,里面有非常实用的技巧)

Become an Effective Software Engineering Manager

這個在 Safari online 也有。

第二类,旨在帮助你成为更出色的工程师的书籍:

《Staff Engineer: Leadership beyond the management track》

img

原文有人做了中文翻譯,還開放Gitbook

《The Staff Engineer Path》

The Staff Engineer's Path

這個在 Safari online 也有, 也有 audio book 版本。 我也有心得分享。

第三类,专注于培养更优秀的团队和工作环境的书籍:

《Shape Up》

《Rework》

《Remote》

《It doesn’t have to be crazy at work》

以上書籍帶查詢。

[論文心得] Scaling Up to Excellence: Practicing Model Scaling for Photo-Realistic Image Restoration In the Wild

論文名稱: Scaling Up to Excellence: Practicing Model Scaling for Photo-Realistic Image Restoration In the Wild

image-20240126105037706

Scaleing Up to Excellence: 令人驚艷圖像恢復論文

提出 SUPIR (Scaling-UP Image Restoration),主要有以下方法:

  • 透過 prompt 提升修復能力,甚至透過 Negtive Prompt 來加強
  • 超過 2000 萬張超高畫質訓練素材 。

結果在品質上可以看到相當好的成效。

論文: https://arxiv.org/abs/2401.13627

網站: https://supir.xpixel.group/

image-20240126105147093

快速總結

  • 研究主題:使用生成式先驗和模型縮放的技術,實現針對真實場景的超高質量的圖像恢復方法。
  • 數據集:收集了2000萬張高分辨率、高質量的圖像,每張圖像都有描述性的文本註釋,用於模型的訓練。
  • 創新點:提出了一種通過文本提示來引導圖像恢復的方法,擴展了圖像恢復的應用範圍和潛力。並且引入了負質量提示來進一步提高感知質量。還開發了一種恢復引導採樣方法,以抑制生成式恢復中遇到的保真度問題。
  • 實驗結果:展示了SUPIR的卓越的圖像恢復效果,以及其通過文本提示進行恢復操作的新穎能力。

系統架構

image-20240126105141343

EDM Sampler with Restoration Guidance 的主要內容如下:

  • EDM Sampler with Restoration Guidance 是一種用於圖像修復的採樣方法,它基於擴散模型的原理,並引入了一個新的超參數 τr 來控制採樣過程中對低質量圖像的引導程度。
  • 目的:該方法的目的是在保持圖像的感知質量的同時,提高圖像的忠實度,即使圖像在採樣過程中不會偏離低質量圖像的內容。
  • 原理:該方法的原理是在每一步的採樣中,根據 τr 的大小,將預測的結果 zt−1 與低質量圖像 zLQ 進行一定比例的混合,使得 zt−1 在保留生成的細節和紋理的同時,也接近於 zLQ。
  • 效果:該方法的效果通過在不同的合成和真實的低質量圖像上的實驗進行了驗證,並與其他的圖像修復方法進行了比較。結果顯示,該方法在非參考指標上取得了最好的表現,並在全參考指標上也有不錯的表現。此外,該方法還可以通過調整 τr 的大小,實現對圖像修復的靈活控制,從而達到不同的效果。

[Golang][Notion] 如何透過 Golang 來操控 Notion DB 當成線上資料庫

Notion Databases: An advanced tutorial on Notion's game-changing feature

前提

在撰寫許多 Side Project 的時候,除了網路服務伺服器之外,最困擾的大概就是資料庫的問題。雖然之前我的文章 [學習心得][Golang] 把 Github Issue 當成資料庫來用 曾經教過透過 Github Golang API 來將簡單的一些資料放在 Github Issue 上,但是如果資料格式比較複雜的時候。可能就會需要透過類似資料庫格式的儲存體來處理。 偏偏許多線上資料庫都是算時間與用量,對於想寫一些有趣的 Side Project 卻沒有那麼友善。

本篇文章將使用 Notion Database 作為資料的儲存體,並且透過 Golang 去查詢,插入相關的資料處理。 本篇文章也會從如何設定一個 Notion Integration 開始教導,讓你透過 Golang 來操控 Notion Database 沒有任何痛苦。

本篇文章將透過: https://github.com/kkdai/linebot-smart-namecard 來說明。

關於 Notion Database

以上是一段 Notion 官方教學影片 Notion Database 裡面有提到如何建立一個 Database ,並且有稍微解釋:

  • Create -> 選擇 Database 欄位中 -> Table

使用 Notion Database 的好處:

image-20240115211147923

  • Notion Database 支援相當豐富的格式,並且有很漂亮的視覺化介面。
  • 並且 Notion Database 支援多種格式: Table, Board, Calendar, List, and Gallery
  • 除了蠻方便 coding 之外,如果有後台管理員,可以透過 Notion UI 來直接查看結果。

建立 Notion Integration

可以先到 Notion Developer 建立第一個 Notion Integration :

image-20240115233258526

  • Type: Internal 只有你可以用,其他人沒有辦法選到。
  • Name: 只要可以辨識就好。

這樣就可以建立了 Integration ,並且取的 Internal Integration Secret (Notion API Key):

image-20240115233433452

開啟 Notion Database 讓 Notion Integration 可以存取:

記得要讓 Notion 頁面取得 Integration 權限 ,參考以下圖片。

官方給的 GIF 檔案相當的清楚,這也是最重要的其中一步。要讓你的資料可以讓 Integration 存取。

取得 Notion Database ID

這也是一個相當重要的事情,要使用 Golang 去存取你的 Notion Database 就需要以下兩個資料:

  • Notion Internal Integration Secret (API Key)
  • Notion Page ID

Notion DB 的頁面網址應該是 https://www.notion.so/b764xxxxxa?v=dexxxx1 那麼 b764xxxxxa就是你的 DatabasePageId。

了解 Notion Database Data Type:

在準備要連接 Notion Database 的時候,你必須要先知道每個欄位的差別。

image-20240115234749333

以我的資料庫為例子:

  • UID: 存放 LINE OA User UID,做為辨識之用。資料格式是: Text

image-20240115234848362

  • 其他都是 Title, Address, Email, Phone Number 。
  • Name: 使用了 Title 這個資料格式,其中差別為: Title 只能有一個欄位,並且會變成新頁面的標題。

image-20240115235405588

開始撰寫 Golang Notion Database 程式碼:

這邊使用的套件是: https://github.com/jomei/notionapi

先了解資料架構

// Person 定義了 JSON 資料的結構體
type Person struct {
	Name        string `json:"name"`
	Title       string `json:"title"`
	Address     string `json:"address"`
	Email       string `json:"email"`
	PhoneNumber string `json:"phone_number"`
}

// DatabaseEntry 定義了 Notion 資料庫條目的結構體。
type NotionDB struct {
	DatabaseID string
	Token      string
}
  • Person: 來自名片掃描的 JSON 資料,也代表這裡每個欄位的資料。除了 UID 是要透過參數進來的。
  • NotionDB:啟動 Notion 需要知道的資料:
    • Token: 就是 Notion Integration Secret
    • DatabaseID: 在 URL 即可取得。 Notion DB 的頁面網址應該是 https://www.notion.so/b764xxxxxa?v=dexxxx1 那麼 b764xxxxxa就是你的 DatabasePageId。
// QueryDatabase 根據提供的屬性和值查詢 Notion 資料庫。
func (n *NotionDB) QueryDatabase(UId, property, value string) ([]Person, error) {
	client := notionapi.NewClient(notionapi.Token(n.Token))

	// Add UId to the filter conditions
	// 建立查詢過濾條件
	filter := &notionapi.DatabaseQueryRequest{
		Filter: notionapi.AndCompoundFilter{
			notionapi.PropertyFilter{
				Property: property,
				RichText: &notionapi.TextFilterCondition{
					Equals: value,
				},
			},
			notionapi.PropertyFilter{
				Property: "UID",
				RichText: &notionapi.TextFilterCondition{
					Equals: UId,
				},
			},
		},
	}

	// 調用 Notion API 來查詢資料庫
	result, err := client.Database.Query(context.Background(), notionapi.DatabaseID(n.DatabaseID), filter)
	if err != nil {
		return nil, err
	}

	var entries []Person

	for _, page := range result.Results {
		entry := n.createEntryFromPage(&page)
		entries = append(entries, entry)
	}
	return entries, nil
}

這一段需要注意的是:

  • 過濾條件使用的是 AndCompoundFilter ,也就是要兩個條件 A && B 。
  • 其中要注意的 PropertyFilter如果資料格式不同的時候,需要處理不同資料。
    • Text: TextFilterCondition
    • Title: TitleFilterCondition
  • 依此類推。

再來看如何新增資料

// AddPageToDatabase adds a new page with the provided field values to the specified Notion database.
func (n *NotionDB) AddPageToDatabase(Uid string, name string, title string, address string, email string, phoneNumber string) error {
	client := notionapi.NewClient(notionapi.Token(n.Token))

	// 建立 Properties 物件來設置頁面屬性
	properties := notionapi.Properties{
		"UID": notionapi.RichTextProperty{
			RichText: []notionapi.RichText{
				{
					PlainText: name,
					Text:      &notionapi.Text{Content: Uid},
				},
			},
		},
		"Name": notionapi.TitleProperty{
			Title: []notionapi.RichText{
				{
					PlainText: name,
					Text:      &notionapi.Text{Content: name},
				},
			},
		},
		// Address, Email, Phone Number....
	}

	// 創建一個新頁面的請求
	pageRequest := &notionapi.PageCreateRequest{
		Parent: notionapi.Parent{
			DatabaseID: notionapi.DatabaseID(n.DatabaseID),
		},
		Properties: properties,
	}

	// 調用 Notion API 來創建新頁面
	_, err := client.Page.Create(context.Background(), pageRequest)
	if err != nil {
		log.Println("Error creating page:", err)
		return err
	}

	log.Println("Page added successfully:", Uid, name, title, address, email, phoneNumber)
	return nil
}
  • 大部分程式碼都是類似的,但是根據欄位不同。需要調整以下內容:
"UID": notionapi.RichTextProperty{
			RichText: []notionapi.RichText{
				{
					PlainText: name,
					Text:      &notionapi.Text{Content: Uid},
				},
			},
		},
  • 其中的 name 是固定參數,不能改。
  • 只有後面的 Content: Uid 可以改。

  • 此外,根據欄位不同 RichTextProperty 也會變動。如果不正確,就無法正確地寫入資料。

最後測試範例程式碼:

func TestAddNotionDB(t *testing.T) {
	token := os.Getenv("NOTION_INTEGRATION_TOKEN")
	pageid := os.Getenv("NOTION_DB_PAGEID")

	// If not set token and pageid , skip this test
	if token == "" || pageid == "" {
		t.Skip("NOTION_INTEGRATION_TOKEN or NOTION_DB_PAGEID not set")
	}

	db := &NotionDB{
		DatabaseID: pageid,
		Token:      token,
	}

	err := db.AddPageToDatabase("uid", "name", "title", "address", "[email protected]", "phone")
	if err != nil {
		t.Fatal(err)
	}
}

參考資料:

[遊戲天國] FF15 全破

FF15 全破了, 同時有玩 FF16 (用 PS Portal) 跟 FF15 (Steam Deck) ,後來竟然覺得 FF15 比較讓我玩得下去。 很專心地把它破關了。

  • 一開始為人詬病的開車兜風那段,我覺得很悠閒。

  • FF15 的相當多樣的支線任務我還蠻喜歡的,不論陸行鳥,拍照任務,還是武器鍛鍊任務。

  • 最後的三個好友單挑歷代王,很感人啊。

  • 幾個 DLC 慢慢留著玩,應該要準備人龍8 惹。

找了一下劇情完結:

關於本傳的解釋:

image-20240115225004791

image-20240115225020138

[研討會心得] NV TW LLM Developer Day 2024

image-20240111122733576

活動資訊

NVIDIA LLM Developer Day重播)

  • 09:30 - 11:00 台灣時間 - 議程 1: 開發大型語言模型 (LLMs) 的快速途徑: slide

  • 11:10 - 12:50 台灣時間 - 議程 2a:量身客製自己的大型語言模型應用:slides

  • 15:30 台灣時間 - 議程 2b:生物科學大型語言模型和生成式人工智慧

  • 17:10 台灣時間 - 議程 3:運行自己的大型語言模型

議程 1: 開發大型語言模型 (LLMs) 的快速途徑

案例 (1) - 音樂公司的客服系統

image-20240111095051777image-20240111095054776

  • 第一個案例: 透過 LLM 來做樂器商的客服系統。
  • 收到客戶 email, 客戶 tag
  • 根據問題找出 RAG 可能的回覆。(顯示於下方),幫助客服回覆。

感想:

  • 竟然用 OpenAI 而非 LLAMA 以 NV DevDay 來說有點怪。
  • 裏面 OpenAI 版本是 < 1.0 , 但是 Openai package 在 11/07 就已經更新到 1.0。(因為當初還被雷到)

1.1 解讀 email 的 prompt

image-20240111095509845

  • 分條列出好的地方跟不好的地方。
  • 分類緊急性。
  • 判斷信件的口吻
  • 結構化輸出

1.2 分析的 Prompt

image-20240111095935738

  • 資料處理的 prompt

image-20240111100529570

  • 格式化輸出的 prompt

image-20240111100620053

  • 透過 COLANG 來定義使用者資料流。

尚未公開產品 Nemotron-3

image-20240111102836188

  • NeVA (NeMo Vision and Language Assistant)

其他:

GTC 2024 - 實體 GTC 03/18。

更多參考:

[打造自己的知識系統] Part 1: 整理資訊流 with IFTTT

image-20240109113904905

(From PlantUML)

總結

我一直以來都是一個喜歡東看西看的人(聽說很多人跟我一樣),但是一直以來資訊流的整理一直是我很痛苦的事情。接下來可能會有一系列的文章記錄著我邊打造個人 LLM KM 系統的時候的一些記錄跟想法。

資訊流

原本資訊流還蠻簡單的,就是希望所有的資訊可以透過 twitter 去當 gateway 然後開始轉到其他地方。 這裡有點麻煩得時候,自從 Twitter 再也不接受免費 API 的申請後(最便宜 100$USD) 。 只好去購買 IFTTT 的服務幫我把資訊從 Twitter 打到 Webhook 。 這邊我以前有類似的文章:

看到五年前開始打造的時候才 10 ~ 20 github issue ,現在卻有 1.3k 的數字。開始思考要如何整理相關資訊。

更多參考: