2025년 4월 21일 월요일

비트넷 1.58, bitnet 1.58 윈도우 빌드 안될때 chrono bitnet 1.58 chrono

검색이 걸릴지 모르겠습니다.

윈도우 빌드 해볼라고 했는데 참 c++ 안한지 오래라 많이 해맸네요


기본적으로는 github의 설치 가이드대로 하면 됩니다.


git clone --recursive https://github.com/microsoft/BitNet.git

cd BitNet


# (Recommended) Create a new conda environment

conda create -n bitnet-cpp python=3.9

conda activate bitnet-cpp


pip install -r requirements.txt


# Manually download the model and run with local path

huggingface-cli download microsoft/BitNet-b1.58-2B-4T-gguf --local-dir models/BitNet-b1.58-2B-4T

python setup_env.py -md models/BitNet-b1.58-2B-4T -q i2_s



일단 clang, cmake 관련은 하단으로 내리면 윈도우 관련 글이 있다.

"C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\Tools\VsDevCmd.bat" -startdir=none -arch=x64 -host_arch=x64

아나콘다 프롬프트로 해당 명령을 하면 되는데 위치가 다를 수 있기 때문에 배치 파일을 만들어서 하면 좋다.

매번 해야 하기 때문에 번거롭다.

visual studio도 c++ 개발 등 cmake 관련과 clang 으로 검색해서 나오는것들 설치해주고 하면 된다.



근데 제목의 내용은 하여간 이렇게 하란대로 다 했는데 안 된다.

그래서 llm 으로 물어보니 이러고 저러고 나오는데

간단하게 

C:\BitNet\3rdparty\llama.cpp\common

common.cpp
log.cpp

이렇게 2개에서 문제가 생기는데

error : no type named 'system_clock' in namespace 'std::chrono'


하여간 저 2개의 파일 상단에 보면

#include "log.h"

#include <condition_variable>
#include <cstdarg>
#include <cstdio>
#include <mutex>
#include <sstream>
#include <thread>
#include <vector>
#include <chrono>  <- 추가


이런식으로 해당 라인을 추가해주면 된다.

컴파일 로그를 보내 2개의 파일에서만 문제가 있었고 이후에는 컴파일이 잘 되서 실제로 잘 돌릴 수 있게 되었다.


급하게 글을 적은 이유는 맥으로도 실패(멈춤)했는데 윈도우에서도 안되서 답답했었고 결국

스스로 해결하게 되었는데 나같은 사람 있을까봐 글을 남긴다.

요즘 llm에는 글 긁어서 주면 뭔지 대충 알려줘서 편한거 같다.
하여간 혹시 같은 문제 있으면 이거 보고 해결보시길

2022년 9월 7일 수요일

C# Async/Await Task 속도가 느릴 때 (TaskCompletionSource)

고전적인 개발 방법으로는 작업이 끝났는지 확인하기 위해서

작업 내용을 확인하는 루프를 만들어서 확인을 하는데


나는 이걸 mysql 풀링에 사용했었다.


그러니까 지금 사용 가능한 mysql 연결이 있는지를 task 에서

루프 돌면서 확인하는 방식으로 만들었던 것이다.


그런데 처음에 async/await task 방식이 문제라고 잘못 생각했던 것이

cpu 점유율을 너무 많이 먹었던 것이다.


ram이나 다른 리소스는 문제가 되지 않았다.

그저 cpu 점유율만 높았다. 그래서 이거 계속 써야 하나 싶었다.

그런데 써보니까 async 에서의 순차 실행이 참 편한 부분이 많았고

해결책을 찾아보니 내 코딩 스타일과 맞지 않았던 것이다.


루프 돌면서 쉬는 mysql 연결을 찾는 코드가 문제였는데

전체 확인하고나서 Task.Yield() 해서 한펌 쉬는 코드를 해놨는데

이게 유니티에서의 1프레임 단위가 아니었던 것이다.

결국 mysql 커넥션이 전부 사용중일때 많은 task 들이 yield를 하면서

루프를 도는데 이 텀이 너무 짧다보니 거의 무한루프(?) 돌듯이 계속 체크하면서

cpu를 다 먹었었다.


그래서 task 관련 공부를 더 했고 해결책을 찾았는데 그게

TaskCompletionSource였다.

값이 맞춰질때까지 대기하는 것이기 때문에 mysql을 다 쓴 후 반환하는 코드에서

mysql 연결 인덱스를 맞춰주니 yield를 사용할 필요가 없어서 cpu 사용율이

획기적으로 내려갔다.


사실 이건 내 코딩 스타일이 오래되서 그런거 같다. 하여간 문제는 해결이 되었고

이제 cpu 점유율 문제는 사라졌다.


2022년 4월 3일 일요일

C# CSV 파싱(여러줄 가능)

이전에는 데이터를 엑셀 데이터를 이용했는데 이건 좀 아닌거 같더라

그래서 CSV를 쓰려고 했는데 여러줄이 들어간 경우 때문에 안 쓰게 되었다.

이번에 현지화 관련 작업을 하면서 CSV를 쓰자고 생각이 들었고

CSV에서 어떤 방식으로 저장하는지를 연구해보았다. 일단 잘 동작한다. 

 
public static void ParsingCSV(string file_name,ref string[][] ret)
{
    ret = null;
    string all = ReadAllText(file_name);
    List<List<string>> lines = new List<List<string>>();
    List<string> ln = new List<string>();
    StringBuilder sb = new StringBuilder();
    bool is_string = false;
    int last = all.Length - 1;
    for(int i = 0; i < all.Length;++i)
    {
        Char c = all[i];
        if (is_string)
        {
            if (c == '"')
            {
                if (i < last && all[i + 1] == '"')
                { // " 2개가 연달아나오면 " 문자열을 써주면 된다.
                    sb.Append('"');
                    ++i;
                }
                else
                { // 문자열이 끝나는 상황
                    ln.Add(sb.ToString());
                    sb.Clear();
                    is_string = false;
                }
            }
            else sb.Append(c);
        }
        else
        {
            if (c == '"') is_string = true; // 문자열의 시작이다.
            else if (c == 0x0d)
            {
                ++i; // \r\n
                if (sb.Length > 0) ln.Add(sb.ToString());
                lines.Add(ln);
                sb.Clear();
                ln = new List<string>();
            }
            else if (c == ',')
            {
                if (sb.Length > 0)
                {
                    ln.Add(sb.ToString());
                    sb.Clear();
                }
                else ln.Add("");
            }
            else sb.Append(c);
        }
    }
    if (lines.Count <= 0) return;
    ret = new string[lines.Count][];
    for (int i = 0; i < ret.Length; ++i) ret[i] = lines[i].ToArray();
}
 "",",\r,\d, , 이 정도만 처리하면 되더라. 

 앞으로는 csv로 써보면서 문제 있으면 위 코드를 수정하게 될 것이다.

2022년 3월 12일 토요일

[윈도우 스토어] 워커홀릭

워커홀릭은 윈폼을 이용한 간단한 프로그램입니다.




구조

1. 상단 트리구조로 당장 업무에 필요한 내용을 정리합니다.

2. 하단 메모장에 필요한 내용을 정리합니다.


끝입니다.


시스템 트레이에 두고 관리할 수 있으며 언제든지 쉽고 빠르게 수정할 수 있습니다.

당장 가볍게 훅훅 들어오는 내용을 정리해 놓았다가 업무툴에 반영하기 좋습니다.

장기가 아니 당장 할 목록을 적었다가 지우면서 사용하면 좋습니다.


개인정보 취급 방침

이 앱은 설치형앱이고 아무런 인터넷 통신을 하지 않습니다.

어떠한 개인정보도 수집하지 않습니다.


2022년 3월 9일 수요일

IP로 국가 코드 얻기 KISA & DB BROWSER FOR SQLITE

 ip로 국가 확인 api


검색어로 구글 검색을 해보니 KISA에서 CSV를 배포하는 것을 알게 되었다.

일반적으로 GEOIP 검색해보면 유료 서비스가 있는데 돈 쓰는 것은 아깝고

PHP등에서는 예전 형식을 사용하는 것이 있는데 난 Dotnet을 사용하는데

데이터만 있으면 좋겠는데...  하고 아쉬워 했었다.


하여간 csv를 먼저 받도록 하자


kisa 국가별 ip


검색어로 검색을 하면

https://xn--3e0bx5euxnjje69i70af08bea817g.xn--3e0b707e/jsp/statboard/IPAS/ovrse/total/currentV4Addr.jsp

위 url로 들어가볼수 있다. (이상한 문자로 보이지만 주소창에 한글로 되어 있다.)


해당 사이트에서 csv를 받도록 한다.


내용은 아래와 같다




사실 여기서 필요한 정보는 국가코드,시작IP,끝IP 3가지다.

나머지열은 지워버린다. 그리고 1줄에 헤더 부분(한글) 도 지워버린다.

db browser for sqlite 를 켜고 데이터베이스를 만든다.

테이블은 안 만들어도 된다. (가져오기 하면 임시 테이블 만들어지니까 이거 수정하자)





파일을 지정하면 아래와 같이 나온다.


가져오기 하면 지 맘대로 테이블 만들어준다.


정보는 원하는대로 입력한다.


데이터가 제대로 입력된것을 볼 수 있다.


공격 들어오는 ip를 조회해보았다.



쿼리는 아래와 같다.

SELECT code from geoip where start <= '168.76.2.6' and end >= '168.76.2.6'

'168.76.2.6' <- 여기에 아이피 넣으면 되고 code 가 없을수도 있다.

이럴경우 특정 값으로 만들어 주고 나중에 다른 서비스를 이용해서 등록해주면

되지 않을까 싶다. 그리고 가능하면 주기적으로 확인해서 최신 데이터로 갈아주는것도

좋을 것이다.


%% 주의 %%

이거 문자열을 숫자형태로 변환해서 사용해야 합니다.

검색하면 나올건 sqlite에는 명령어가 없고 mysql 에서는 INET_ATON 명령어로

변환해서 사용해야 제대로 검색이 됩니다.

글을 수정하거나 새로 쓰기 귀찮아서 아래에 추가 합니다.

2022년 2월 27일 일요일

C# Litjson Extension

저는 C# 개발을 할때 json 라이브러리는 Litjson을 주로 사용합니다.


편하게 사용하기 위해서 정적 클래스 하나 만드러서 사용하다가 이번에는 익스텐션을 만들어 보았습니다.


확실히 편하게 사용할 수 있는 부분은 찾아보는 것이 좋은것 같습니다.


사용하는 litjson 라이브러는 0.17.0 버전입니다. 이전이나 이후도 별 상관은 없을것 같네요.

dotnet6로 만든 소스구요 null에 대한부분 ? 없애는 정도면 되지 않을까 싶네요.


사용법은

JsonData jd;

jd.GetInt();

jd.GetString();

아래 소스를 보시면 아시겠지만 어떻게든 값을 얻어옵니다.

타입 체크가 필요하면 하고 하면 될것이구요.

IsNumber의 경우 숫자 형태가 너무 많아서 추가했습니다.

필요한 것이 있으면 더 추가하면 될것이구요.

하여간 도움이 되면 좋겠습니다~


파일을 올릴수가 없네요.

소스입니다.

namespace LitJson
{
    internal static class LitjsonExtension
    {
        public static bool IsNumber(this JsonData jd)
        {
            switch (jd.GetJsonType())
            {
                case JsonType.Int:
                case JsonType.Long:
                case JsonType.Double: return true;
                default: return false;
            }
        }
        public static bool GetBool(this JsonData jd)
        {
            if (jd == null) return false;
            switch (jd.GetJsonType())
            {
                case JsonType.String: return Convert.ToBoolean((string)jd);
                case JsonType.Int: return Convert.ToBoolean((int)jd);
                case JsonType.Long: return Convert.ToBoolean((long)jd);
                case JsonType.Double: return Convert.ToBoolean((double)jd);
                case JsonType.Boolean: return (bool)jd;
                case JsonType.None:
                case JsonType.Object:
                case JsonType.Array:
                default: return false;
            }
        }
        public static int GetInt(this JsonData jd)
        {
            if (jd == null) return 0;
            switch (jd.GetJsonType())
            {
                case JsonType.String: return Convert.ToInt32((string)jd);
                case JsonType.Int: return (int)jd;
                case JsonType.Long: return Convert.ToInt32((long)jd);
                case JsonType.Double: return Convert.ToInt32((double)jd);
                case JsonType.Boolean: return Convert.ToInt32((bool)jd);
                case JsonType.None:
                case JsonType.Object:
                case JsonType.Array:
                default: return 0;
            }
        }
        public static long GetLong(this JsonData jd)
        {
            if (jd == null) return 0;
            switch (jd.GetJsonType())
            {
                case JsonType.String: return Convert.ToInt64((string)jd);
                case JsonType.Int: return Convert.ToInt64((int)jd);
                case JsonType.Long: return (long)jd;
                case JsonType.Double: return Convert.ToInt64((double)jd);
                case JsonType.Boolean: return Convert.ToInt64((bool)jd);
                case JsonType.None:
                case JsonType.Object:
                case JsonType.Array:
                default: return 0;
            }
        }
        public static double GetDouble(this JsonData jd)
        {
            if (jd == null) return 0;
            switch (jd.GetJsonType())
            {
                case JsonType.String: return Convert.ToDouble((string)jd);
                case JsonType.Int: return Convert.ToDouble((int)jd);
                case JsonType.Long: return Convert.ToDouble((long)jd);
                case JsonType.Double: return (double)jd;
                case JsonType.Boolean: return Convert.ToDouble((bool)jd);
                case JsonType.None:
                case JsonType.Object:
                case JsonType.Array:
                default: return 0;
            }
        }
        public static string? GetString(this JsonData jd)
        {
            if (jd == null) return null;
            switch (jd.GetJsonType())
            {
                case JsonType.Object:
                case JsonType.Array: return jd.ToJson();
                case JsonType.String: return (string)jd;
                case JsonType.Int: return Convert.ToString((int)jd);
                case JsonType.Long: return Convert.ToString((long)jd);
                case JsonType.Double: return Convert.ToString((double)jd);
                case JsonType.Boolean: return Convert.ToString((bool)jd);
                case JsonType.None:
                default: return null;
            }
        }
    }
}

gtr9 pro, ai max+ 395, gpt-oss-120b 돌아간다~!

여러가지 샛팅을 해봤지만 잘 안되는 상황에서 검색을 해보니까 레모네이드 서버를 이용해서 amd에서 서빙하는것을 발견했다. 일단 윈도우에서 ram 64g vram 64g에서 돌아는 가는데 컨텍스트가 낮았다. 그런데 속도가 빠르고 gpu를 다 쓰길래 희망...