Recently, TrueNas Fangtooth 25.04 was release. The VM system has changed compared to the previous version.
A new ‘Instances’ menu has been introduced for managing virtual machines. If you were using Windows 10 with a prrevious version of TrueNas, you will need to create a new VM.
This document outlines the necesary steps.
Import Zvols from the previous version. I prefer cloning over moving for data backup.
2. I’ve also uplaed GParted and the Windows ISO. In my case, I encounted a timeout error while uploading a large ISO file (Windows). If you experience the same issue, i’ll create another post to address it. Gparted – https://downloads.sourceforge.net/gparted/gparted-live-1.7.0-1-amd64.iso
I’ve added the import windows disk, gparted live iso and enable VNC.
4. Remove unsued paritions and create a new partition. Changed the parition to GPT partition.
You NEED to select the correct disk. I chose it based on the size. This is an important step.
Remove all other partitions excep the main one. In my case, the 78G partion was the windows. I’m not sure what the othere were. The boot partion shoudl be fat32 but in my case, it was NTFS which caused a boot issue.
Try to convert the partitions to GPT. – Click Terminal. sudo gdisk /dev/diskname (based on right top side information) w – y . then you can see complete.
Return to GUI gparted – refresh the devices.
Create a partition EFI and fat32 on first area.
Shutdown the device.
5. Resotre the boot area with windows ISO.
insert the windows_iso
Boot windows 10 Setup.
Below is korean. but you can click same button.
Restore the partition.
diskpart list disk select disk ? (based on size) list partition select partition 1 assign letter=s
bootrec /scanos bcdboot d:\windows /s S: /f UEFI
DONE! 6. Reboot the device and wait. It may reboot a few times. Eventually, you will see Windows
현재 KB증권을 이용중이다.. 나는 혜택이 있지만 HTS (PC거래)시만 적용이 되고, 아이들 계좌는 일반 수수료 (0.25%) 이다.
최근에 KB에서 여러 이벤트도 있길래 좀 어떻게 될꺼가 있나 해서 지점과도 통화 했지만 그냥 증권사를 옮기라고 한다. 그래서 몇 곳을 알아 보고 결정을 했다.
중심으로 둔거는 아이들 계좌이다. 지금 현금 2~3만원 주는 곳은 많은데, ‘평생’ 수수료를 주는 곳으로 택했다.
그래서 삼성증권은 평생 수수료. 0.03%(미국) . 일반적으로 0.25%니깐.. 당장 몇만원 안줘도, 좀 거래 하다보면 이벤트 3만원 정도 효과가 있다. 장기적으로 보면 이것만으로도 충분히 이익이다. 그러나 현재 계좌를 옮기면 그걸로 이벤트를 준다. 결론적으로 보면 평생 + 타행 이동의 경우 가장 좋은 효과를 보여 준다.
아래는 미래에셋 이다. 2만원 기본으로 주고, 주식 거래 하면 2~3만원 정도 추가로 받을수 있을것 같다. 그러나 평생은 아니다.
얼마전에 사진 정리 도구를 Piwigo에서 PhotoPrism으로 변경했습니다. Piwigo는 매우 좋은 어플리케이션이지만, PhotoPrism의 현대적인 느낌과 AI를 이용한 사진 분류기능이 매력적입니다. PhotoPrism은 Golang으로 개발되어 있으며, REST API를 통해 다양한 프로그래밍 언어로 활용할 수 있습니다. (Browse Your Life in Pictures – PhotoPrism). 그러나 여러 예시가 Golang이라 그것을 활용해 보았습니다. Golang은 처음이로 ChatGPT를 이용해서 Library와 Sample을 만들었습니다.
AzureAI를 사용해 태그를 추가하고, Piwigo의 사진을 PhotoPrism에 업로드 하는 것이 골이 었고, AzureAI를 사용한 이유는 일정범위(개인용으로 충분한)에서 무료 사용기 가능하다는 점입니다.
go mod init azure-golang go mod tidy export VISION_KEY="YOURKEY" go run
실행 코드
package main
import (
"github.com/flywithu/azure-golang"
"fmt"
"log"
"os"
"net/http"
"io"
)
func main() {
VISION_ENDPOINT := "https://flywithufreevision.cognitiveservices.azure.com"
VISION_KEY := os.Getenv("VISION_KEY")
filePath:="temp.jpg"
// URLs for image analysis
landmarkImageURL := "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/landmark.jpg"
kitchenImageURL := "https://learn.microsoft.com/en-us/azure/ai-services/computer-vision/images/windows-kitchen.jpg"
eiffelTowerImageURL := "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Eiffel_Tower_20051010.jpg/1023px-Eiffel_Tower_20051010.jpg"
redShirtLogoImageURL := "https://publish-p47754-e237306.adobeaemcloud.com/adobe/dynamicmedia/deliver/dm-aid--08fdf594-c963-43c8-b686-d4ba06727971/noticia_madridistas_hp.app.png?preferwebp=true&width=1440"
client := vision.ComputerVisionClient(VISION_ENDPOINT, VISION_KEY)
log.Println("++++++++++++++++++++++++++++++++++++++++++++++++")
log.Println("Download File")
resp, err := http.Get(landmarkImageURL)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, err := os.Create(filePath)
if err != nil {
panic(err)
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
panic(err)
}
// Tagging an image
log.Println("++++++++++++++++++++++++++++++++++++++++++++++++")
log.Println("Image Tagging")
tags, err := client.GetImageTags(filePath)
if err != nil {
log.Fatalf("Failed to get image tags: %v", err)
}
for i, tag := range tags.Tags {
if i >= 3 { break }
fmt.Printf("Tag: %s (Confidence: %.2f)\n", tag.Name, tag.Confidence)
}
// Describing an image
log.Println("++++++++++++++++++++++++++++++++++++++++++++++++")
log.Println("Image Description")
description, err := client.GetImageDesc(filePath)
if err != nil {
log.Fatalf("Failed to get image description: %v", err)
}
for i, tag := range description.Description.Tags {
if i >= 3 { break }
fmt.Printf("Description Tag: %s\n", tag)
}
for i, caption := range description.Description.Captions {
if i >= 3 { break }
fmt.Printf("Caption: %s (Confidence: %.2f)\n", caption.Text, caption.Confidence)
}
// Object Detection
log.Println("++++++++++++++++++++++++++++++++++++++++++++++++")
log.Println("Object Detection")
objects, err := client.GetImageObject(kitchenImageURL)
if err != nil {
log.Fatalf("Failed to detect objects: %v", err)
}
for i, obj := range objects.Objects {
if i >= 3 { break }
fmt.Printf("Object: %s (Confidence: %.2f)\n", obj.ObjectInfo.ObjectName, obj.ObjectInfo.Confidence)
if obj.Parent != nil {
fmt.Printf("Parent Object: %s (Confidence: %.2f)\n", obj.Parent.ObjectName, obj.Parent.Confidence)
}
}
// Analyzing image for landmarks
log.Println("++++++++++++++++++++++++++++++++++++++++++++++++")
log.Println("Landmark Analysis")
landmarks, err := client.GetImageAnalyze(eiffelTowerImageURL)
if err != nil {
fmt.Printf("Failed to analyze landmarks: %v", err)
}
for i, cat := range landmarks.Categories {
if i >= 3 { break }
fmt.Printf("Category: %v\n", cat)
if cat.Detail != nil && len(cat.Detail.Landmarks) > 0 {
fmt.Printf("Landmark: %v\n", cat.Detail.Landmarks[0].Name)
}
}
// Analyzing brands
log.Println("Analyze - Brands")
brands, err := client.GetImageAnalyze(redShirtLogoImageURL)
if err != nil {
fmt.Printf("Failed to analyze brands: %v", err)
}
fmt.Printf("Brand : %v \n",brands.Brands)
for i, tag := range brands.Tags {
if i >= 3 { break }
fmt.Printf("Brand Tag: %v \n", tag)
}
}
I recently switched my photo organization tool from Piwigo to PhotoPrism. While Piwigo is a very good application, I found PhotoPrism’s modern UI and AI-powered photo capabilities appealing. PhotoPrism is developed in Golang and can be utilized with various languages through its REST API. However, since many examples are in Golang, I decided to use that. As it was my first time using Golang, I wrote libraries and samples with ChatGPT guidance.
Adding tags with Azure AI and uploading photos to PhotoPrims was the goal, and the reason for using Azure AI is that it offers free usage, which is sufficient for personal use.
Android의 CTS를 TC를 확인하면서, DRM항목 중 Clearkey TC에 관심이 생겼습니다. DRM은 디지털 콘텐츠의 무단 복제를 방지 하는 기술로, 저작권 보호에 핵심적인 역할을 합니다. 이 기술에 실제로 어떻게 작동하는지 궁금해서 다음과 같은 리소스도 참고 했습니다.
Clearkey는 간단하고 비용 효율적인 DRM으로, 주로 보안 요구사항이 낮은 콘텐츠에 적용됩니다. 반면 Google에서 개발한 Widevine은 훨씬 높은 보안을 제공합니다. Widevine은 세가지 보안 수준(L1,L2,L3)를 가지며, 이는 HW와 SW사용 여부에 달라집니다. L1과 L2는 HW를 사용하여 보안을 강화하지만, L3는 소프트웨어만을 사용하고 보통 480p해상도 까지 지원 합니다.
Coupang Play의DRM
현재 OTT는 Netflix, Disney, Tving, CoupangPlay, youtube 를 구독 중입니다. 최근 Coupang Play가 가격인상을 하였기에, 향후에도 계속 사용할지 모르겠습니다. 그래서 권한이 있을때 확인 해보고자 했습니다.
DRM 및 관련 자료를 찾는 사전 준비대비, 코덱 코드에 이미 DUMP 준비가 다 되어 있고, Define만 살렸더니 실험해보려던거가 한번에 되어서 좀 허망함이 있었습니다.
그러나 이번에 DRM의 구조 이해와 미디어쪽을 알게 되었습니다. 이론적으로는 FakeCodec과 같은 사용자 정의 코덱을 만들면 DRM 보호 데이터를 덤프 할수 있음을 확인 했습니다.
DRM으로 보호된 것을 사적 복사를 넘어선 제 3자에게 공유하는 것은 금지되어 있습니다. 그리고 다른 ID로 덤프해서 비교해보면 확실하겠지만, 아마 워터마크가 있을 것이고 이를 통한 추적도 가능 할것 입니다. 이러한 워터마크의 제거를 하려면 인코딩과 디코딩을 반복해서 해야 하고, 그러면 화질 저하가 발생하기 때문에 이것도 방법은 아닙니다..
English
Motivation
While stuying the Android CTS, I became interested in the ClearKey TC within DRM. DRM is a protective technology designed to prevent copying. I’ve reviewd below items.
DRM stands for ‘Digital Rights Management’ , a technology designed to prevent unauthrozied copying and distribution of digital content. And only authorized users recevied the key to access it.
Clearkey is a simple and cost efficient DRM solution, used for content with low security requirments. On the other hand, Widevine, developed by Google, offers much higher security. Widevine has three levels of security(L1,L2,L3) that depend on whether HW or SW is used. L1 and L2 enhances security by HW, L3 uses only SW and typically supports up to 480p resolution.
Coupang Play with DRM
With the recent price increase at Coupang Play, I’m unsure if I’ll continue my subscription. Therefore I hope to thoroughly invetigate the service while I sill have access.
Initially, I intened to experiment only with the ClearKey method. as studying Widevine seemd too challenging. However, rather than giving up, I decied to shift my focus to chekcing if video dumping was possible.
This is the Widevine architecture and lower-right HAL, known s OEMCrypto HAL, decrypts the data and tranfers it to Media Out.
This is the codec architecture. The decrypted data is decoded by the codec and then displayed on screen. I may not be able to decrypt Widevine, I colud intercept and save the input to obtain the decrypted data.
After examing the codec section , I modified the following part to make it operational .
이번 포스트는 MNIST 데이터셋입니다. MNIST는 머신러닝과 컴퓨터 비전 분야에서 ‘Hello world’와 같은 존재 입니다. 이처럼 광범위하게 사용되는 만큼, 다양한 예제와 구현 방법이 널리 알려져 있습니다. 최근에 CPP로 된 MNIST를 돌려 보다가, 기존 python 보다 훨씬 빠른거 같은 느낌이 들어서 실제적인 시간을 측정해 보았습니다.
사실 python 은 GIL, 싱글쓰레드, 인터프리터, 동적 타이핑등의 이유로 CPP보다 느릴수 밖에 없습니다. 그러나 PyTorch는 많은 부분이 저수준 언어를 랩핑하는 것으로 알고 있었기에 예상보다 큰 성능차이를 보이는 결과에 대해서 상당한 의구심이 있습니다. 테스트가 잘못 되었을수도 있기 때문에, 잘못된 점을 알려 주시면 다시 확인 해보겠습니다.
테스트 결과를 보면 DataLoader와 Log Print 에서 수치적으로 큰 차이가 납니다. Python 이 Non-Blocking 으로 I/O처리는 하지만 아무래도 성능 저하가 있는것 같습니다. Log Print 의 경우는 화면에 비출력 해서, DataLoader는 속도를 최적화한 다른 API로 변경이 가능할것으로 보입니다. GPU로 복사하는 시간은 거의 동일한 것으로 봐서는, Python의 관여가 적으면 성능은 유사한것 같습니다.
가장 중요한 학습 부분에서, 초기화 – 학습 의 과정에서 아래 예시에서는 절대적 시간 차이는 적지만, %로 보면은 큰 차이를 보입니다. 이 수치와 학습 모델의 크기도 나중에 비교할 필요가 있습니다. 만약 학습 모델의 크기가 클수록 이 차이가 커진다면, PoC후 튜닝 및 상용화는 언어를 변경하는 것도 고려가 필요해 보입니다.
테스트 수행했던 코드는 colab 에 올렸습니다. 성능차이가 심한것이 아무래도 이상한데 잘못된 점이 있으면 알려 주길 부탁 드립니다. 동일한(유사한)결과를 위해 Colab 결과만 올립니다.
GPU 사용량을 추적할수 있었던 로컬 테스트 결과를 첨언하자면 GPU 사용률에서는 CPP가 월등히 높았습니다. 그러나 CPU만을 이용한 학습의 경우, CPU는 100%에 가까운 사용률을 보이나, GPU를 이용한 학습의 경우는 Cpp의 경우 50%, Python의 경우 DataLoader를 멀티로 돌릴때 30% 사용률을 보였습니다. 그래서 동시에 여러 잡을 돌려서 GPU를 100%까지 사용할수 있다면, 단위시간당 처리량은 cpp와 python이 같을수 있습니다. 이 부분은 더 실험이 필요해 보입니다.
다만 앙상블과 같은 모델을 돌려서 한개의 결과를 뽑는다고 보았을때는, CPP를 이용하는 것이 학습과 결과에 유리 해 보입니다.
각 단계별 설명은 다음과 같습니다. Total Time: 전체 수행 시간 Summed Time: 각 스텝별 수행시간의 합. (vs. Total : Main 프로그램이 도는데 걸리는 시간 제외) Step Count: 학습한 데이터 갯수(확인용) – 동일 수치로 두개의 모델의 일관성을 확인합니다. Data Loading: PyTorch API를 이용한 MNIST 데이터 loading 시간 – 시간 차이가 큰 부분입니다. 언어별 효율성의 차이를 알 수 있습니다. Copying TO GPU: 로딩한 데이터를 GPU로 복사 시간 – GPU 사용을 위한 데이터 복사 시간. 큰 차이 없음. Optimizer Init: 초기화 – 학습 시작전 초기화 입니다. %로 보면 큰 차이를 보입니다. Model Forward: 모델 순전파(입력 예측 생성). %로 보면 큰 차이를 보입니다. 모델의 크기에 따른 비교도 필요 합니다. Loss Calculation: 손실계산 Backward Pass: 역전파 (가중치 조정) Parameter Update: 가중치 업데이트 Progress Printing: Log 출력
The MNIST dataset is described as the ‘Hello World’ of Machine Learning and Computer Vision. It is widely used, with numerous examples and implementations available. Recently, I experimented with the MNIST implementation in C++, and it appeared to run faster than Python. So, I tried to check the actual time.
Python tends to be slower than C++ due to factors like the GIL, single-thread, Interpreted language, and dynamic typing. However, knowing that PyTorch wraps a lot of low-level language functionality, I expected the performance gap between C++ and Python to be minimal. But the significant differences I observed, especially in DataLoader and Log Print times, were curious. While Python used non-blocking I/O, it seems to incur some performance penalty. For log print, avoiding output to the screen and for DataLoader, using an optimized API could potentially improve performance. The time taken to copy data to the GPU was nearly identical, When Python’s involvement is minimal, the performance is similar.
In the important area of machine learning, particularly during initialization and training, the above time difference was small but proportionally significant. This indicates the need for further comparison, especially with larger size models. If bigger models make the performance gap larger, we might think about trying a different programming language before commercialization.
I’ve uploaded the test code to Colab. The significant performance difference seems unusual, so let me know of any potential mistakes. To maintain consistency, I’ve shared only the Colab results.
Additionally, I’ve observed GPU usage differences, with C++ utilizing the GPU more effectively than Python. When training solely on CPU, the usage was nearly 100%, but for C++ , the GPU usage was 50% and even lower for Python when trying with multi-threaded data loading. Perhaps maximizing GPU utilization with concurrent tasks could equalize C++ and Python’s performance. We need further investigation.
For ensemble models producing a single result, C++ seems to be more advantageous for machine learning tasks.
The table above provides a more detailed explanation of the time consumed at each step, and the full code is available at the provided URL.
테스트를 효율성을 위해서 emulator 작업 중이었는데, 이것도 중단하고 tmap도 다 삭제 했었습니다. 그러나 emulator는 필요한 분도 있을것 같아 이번에 정리해서 올립니다.
기능은 X86 AAOS(AOSP) emulator (AOSP11): 설정에 따라 phone 및 AAOS 모두 사용 가능 합니다. docker/config 를 aosp_car_x86_64-user 또는 sdk_phone_x86_64-user 로 수정하면 됩니다. arm -> x86 인터프리터 => 이 라이브러리로 arm전용 앱인 tmap도 설치 및 사용 가능. 수도권순환도로를 왔다 갔다 하는 GPS 값 Google Playstore 및 Korean IME 요렇게 있습니다.
참고로 AOSP9용으로도 x86/arm houdini library가 있는데, Tmap이 Android9(API28) 지원한다고는 적혀 있으나, 제가 테스트 했을떄는 API30 (AOSP10)용 API가 사용되는것으로 보였습니다. 실행하다 에러가 나는데 디버깅하다가 그냥 AOSP11로 업그레이드 했습니다.