llama.cpp with CUDA backend 빌드하기

git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
#vcpkg를 설치하세요
vcpkg install curl:x64-windows 
vcpkg integrate install
#저는 A드라이브에 설치해서 경로가 다를 수 있습니다. 이 점 참고하세요.
cmake -B build -DGGML_CUDA=ON -DLLAMA_CURL=ON -DCMAKE_GENERATOR_TOOLSET="cuda=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.4" -DCMAKE_CUDA_ARCHITECTURES="86;89" -DCMAKE_TOOLCHAIN_FILE=A:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCURL_INCLUDE_DIR=A:/vcpkg/packages/curl_x64-windows/include -DCURL_LIBRARY=A:/vcpkg/packages/curl_x64-windows/lib/libcurl.lib

cmake --build build --config Release

빌드 시간이 꽤 걸리니까 시간이 되실 때 하시면 좋을거 같아요.

다음과 같이 빌드가 된 모습을 보실 수 있어요.

PS Q:\llama.cpp\build\bin\Release> ./llama-mtmd-cli.exe -m ./Qwen2-VL-7B-Instruct-Q4_0.gguf –mmproj ./mmproj-Qwen2-VL-7B-Instruct-f32.gguf –image ./lion.png –temp 0.2 -p “describe this image in detail” -ngl 100 –n-gpu-layers 100
ggml_cuda_init: GGML_CUDA_FORCE_MMQ: no
ggml_cuda_init: GGML_CUDA_FORCE_CUBLAS: no
ggml_cuda_init: found 1 CUDA devices:
Device 0: NVIDIA GeForce RTX 4070 Ti, compute capability 8.9, VMM: yes
build: 5868 (0aedae00) with MSVC 19.44.35211.0 for x64
llama_model_load_from_file_impl: using device CUDA0 (NVIDIA GeForce RTX 4070 Ti) – 11038 MiB free
llama_model_loader: loaded meta data with 37 key-value pairs and 339 tensors from ./Qwen2-VL-7B-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 = qwen2vl
llama_model_loader: – kv 1: general.type str = model
llama_model_loader: – kv 2: general.name str = Qwen2 VL 7B Instruct
llama_model_loader: – kv 3: general.finetune str = Instruct
llama_model_loader: – kv 4: general.basename str = Qwen2-VL
llama_model_loader: – kv 5: general.size_label str = 7B
llama_model_loader: – kv 6: general.license str = apache-2.0
llama_model_loader: – kv 7: general.base_model.count u32 = 1
llama_model_loader: – kv 8: general.base_model.0.name str = Qwen2 VL 7B
llama_model_loader: – kv 9: general.base_model.0.organization str = Qwen
llama_model_loader: – kv 10: general.base_model.0.repo_url str = https://huggingface.co/Qwen/Qwen2-VL-7B
llama_model_loader: – kv 11: general.tags arr[str,2] = [“multimodal”, “image-text-to-text”]
llama_model_loader: – kv 12: general.languages arr[str,1] = [“en”]
llama_model_loader: – kv 13: qwen2vl.block_count u32 = 28
llama_model_loader: – kv 14: qwen2vl.context_length u32 = 32768
llama_model_loader: – kv 15: qwen2vl.embedding_length u32 = 3584
llama_model_loader: – kv 16: qwen2vl.feed_forward_length u32 = 18944
llama_model_loader: – kv 17: qwen2vl.attention.head_count u32 = 28
llama_model_loader: – kv 18: qwen2vl.attention.head_count_kv u32 = 4
llama_model_loader: – kv 19: qwen2vl.rope.freq_base f32 = 1000000.000000
llama_model_loader: – kv 20: qwen2vl.attention.layer_norm_rms_epsilon f32 = 0.000001
llama_model_loader: – kv 21: general.file_type u32 = 2
llama_model_loader: – kv 22: qwen2vl.rope.dimension_sections arr[i32,4] = [16, 24, 24, 0]
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,152064] = [“!”, “\””, “#”, “$”, “%”, “&”, “‘”, …
llama_model_loader: – kv 26: tokenizer.ggml.token_type arr[i32,152064] = [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.chat_template str = {% set image_count = namespace(value=…
llama_model_loader: – kv 32: general.quantization_version u32 = 2
llama_model_loader: – kv 33: quantize.imatrix.file str = /models_out/Qwen2-VL-7B-Instruct-GGUF…
llama_model_loader: – kv 34: quantize.imatrix.dataset str = /training_dir/calibration_datav3.txt
llama_model_loader: – kv 35: quantize.imatrix.entries_count i32 = 196
llama_model_loader: – kv 36: quantize.imatrix.chunks_count i32 = 128
llama_model_loader: – type f32: 141 tensors
llama_model_loader: – type q4_0: 194 tensors
llama_model_loader: – type q4_1: 3 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 = 4.13 GiB (4.66 BPW)
load: special tokens cache size = 14
load: token to piece cache size = 0.9309 MB
print_info: arch = qwen2vl
print_info: vocab_only = 0
print_info: n_ctx_train = 32768
print_info: n_embd = 3584
print_info: n_layer = 28
print_info: n_head = 28
print_info: n_head_kv = 4
print_info: n_rot = 128
print_info: n_swa = 0
print_info: is_swa_any = 0
print_info: n_embd_head_k = 128
print_info: n_embd_head_v = 128
print_info: n_gqa = 7
print_info: n_embd_k_gqa = 512
print_info: n_embd_v_gqa = 512
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 = 18944
print_info: n_expert = 0
print_info: n_expert_used = 0
print_info: causal attn = 1
print_info: pooling type = -1
print_info: rope type = 8
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: model type = 7B
print_info: model params = 7.62 B
print_info: general.name = Qwen2 VL 7B Instruct
print_info: vocab type = BPE
print_info: n_vocab = 152064
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: EOG token = 151643 ‘<|endoftext|>’
print_info: EOG token = 151645 ‘<|im_end|>’
print_info: max token length = 256
load_tensors: loading model tensors, this can take a while… (mmap = true)
load_tensors: offloading 28 repeating layers to GPU
load_tensors: offloading output layer to GPU
load_tensors: offloaded 29/29 layers to GPU
load_tensors: CUDA0 model buffer size = 3940.21 MiB
load_tensors: CPU_Mapped model buffer size = 292.36 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: CUDA_Host output buffer size = 0.58 MiB
llama_kv_cache_unified: CUDA0 KV buffer size = 224.00 MiB
llama_kv_cache_unified: size = 224.00 MiB ( 4096 cells, 28 layers, 1 seqs), K (f16): 112.00 MiB, V (f16): 112.00 MiB
llama_kv_cache_unified: LLAMA_SET_ROWS=0, using old ggml_cpy() method for backwards compatibility
llama_context: CUDA0 compute buffer size = 304.00 MiB
llama_context: CUDA_Host compute buffer size = 15.01 MiB
llama_context: graph nodes = 1098
llama_context: graph splits = 2
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)
mtmd_cli_context: 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|>assistant

clip_model_loader: model name: Qwen2-VL-7B-Instruct
clip_model_loader: description: image encoder for Qwen2VL
clip_model_loader: GGUF version: 3
clip_model_loader: alignment: 32
clip_model_loader: n_tensors: 521
clip_model_loader: n_kv: 20

clip_model_loader: has vision encoder
clip_ctx: CLIP using CUDA0 backend
load_hparams: projector: qwen2vl_merger
load_hparams: n_embd: 1280
load_hparams: n_head: 16
load_hparams: n_ff: 0
load_hparams: n_layer: 32
load_hparams: ffn_op: gelu_quick
load_hparams: projection_dim: 3584

— vision hparams —
load_hparams: image_size: 1024
load_hparams: patch_size: 14
load_hparams: has_llava_proj: 0
load_hparams: minicpmv_version: 0
load_hparams: proj_scale_factor: 0
load_hparams: n_wa_pattern: 0

load_hparams: model size: 2577.82 MiB
load_hparams: metadata size: 0.18 MiB
alloc_compute_meta: CUDA0 compute buffer size = 2.33 MiB
alloc_compute_meta: CPU compute buffer size = 0.14 MiB
main: loading model: ./Qwen2-VL-7B-Instruct-Q4_0.gguf
encoding image slice…
image slice encoded in 98 ms
decoding image batch 1/1, n_tokens_batch = 66
image decoded (batch 1/1) in 13 ms

The image depicts a male lion standing in a grassy field. The lion has a robust build, with a large mane that is predominantly dark brown with some lighter shades. Its body is covered in a thick coat of fur, which appears to be a mix of dark and light brown tones. The lion’s tail is long and bushy, and it has a prominent tuft of hair at the end. The lion’s mouth is open, revealing its teeth, and it appears to be roaring or vocalizing. The background consists of a grassy field with no other animals or objects visible. The overall scene suggests a natural habitat, possibly a savannah or grassland.

llama_perf_context_print: load time = 2289.43 ms
llama_perf_context_print: prompt eval time = 351.52 ms / 81 tokens ( 4.34 ms per token, 230.43 tokens per second)
llama_perf_context_print: eval time = 1662.09 ms / 134 runs ( 12.40 ms per token, 80.62 tokens per second)
llama_perf_context_print: total time = 4355.55 ms / 215 tokens

이미지는 풀이 무성한 들판에 서 있는 수컷 사자를 묘사하고 있습니다. 사자는 튼튼한 체격을 가지고 있으며, 큰 갈기는 주로 짙은 갈색이며 약간 더 밝은 색조를 띠고 있습니다. 몸은 짙은 갈색과 연한 갈색 톤이 섞인 두꺼운 털로 덮여 있습니다. 사자의 꼬리는 길고 덥수룩하며 끝에는 눈에 띄는 털이 있습니다. 사자의 입은 열려 있으며 이빨이 드러나 있고 포효하거나 목소리를 내는 것처럼 보입니다. 배경은 다른 동물이나 물체가 보이지 않는 풀이 무성한 들판으로 구성되어 있습니다. 전체적인 장면은 사바나나 초원일 가능성이 있는 자연 서식지를 시사합니다.

깔끔하게 대답이 나오는 군요!

This image is a vibrant and colorful illustration featuring a group of animated characters from the popular anime series “One Piece.” The characters are standing together against a blue sky background, creating a dynamic and lively scene.

1. **Luffy**: In the center, wearing a straw hat and a red jacket, Luffy is the main protagonist of the series. He is known for his艅↑꺐?쒎츩 (艅↑꺐?쒎츩) or rubber fruit, which gives him superhuman strength and flexibility.

2. **Nami**: To the right of Luffy, Nami is depicted with long orange hair and a blue bikini top. She is a navigator and a skilled navigator, often seen using her knowledge of the sea to guide the crew.

3. **Zoro**: To the left of Luffy, Zoro is a swordsman with green hair and a green jacket. He is known for his three swords and his determination to become the strongest swordsman in the world.

4. **Sanji**: Next to Zoro, Sanji is a chef with long blonde hair and a black jacket. He is known for his cooking skills and his love for food.

5. **Chopper**: To the right of Sanji, Chopper is a young doctor with a blue hat and a red coat. He is a cyborg and a member of the Straw Hat Pirates.

6. **Usopp**: To the left of Chopper, Usopp is a marksman with green hair and a green jacket. He is known for his sharpshooting skills and his love for pranks.

7. **Tony Tony Chopper**: To the left of Usopp, Tony Tony Chopper is a cyborg with a red hat and a red coat. He is a doctor and a member of the Straw Hat Pirates.

8. **Franky**: To the right of Tony Tony Chopper, Franky is a cyborg with a blue hat and a blue jacket. He is known for his mechanical skills and his love for music.

9. **Brook**: To the right of Franky, Brook is a musician with a white hat and a white coat. He is a member of the Straw Hat Pirates and a skilled musician.

10. **Boa Hancock**: To the right of Brook, Boa Hancock is a powerful and beautiful woman with long black hair and a blue bikini top. She is known for her strength and her role as the Pirate Empress.

11. **Bepo**: To the left of Hancock, Bepo is a talking dog with a red hat and a red coat. He is a member of the Straw Hat Pirates and a loyal companion to the crew.

12. **Big Mom**: To the right of Bepo, Big Mom is a powerful and fearsome pirate with a large, red, and black body. She is known for her immense power and her role as the Pirate Empress.

The characters are depicted in a variety of poses, some with their arms raised in excitement or determination, creating a sense of camaraderie and adventure. The overall scene is vibrant and?끾빨域삣뒟, reflecting the energetic and adventurous spirit of the “One Piece” series.

이 이미지는 인기 애니메이션 시리즈 ‘ 원피스’의 애니메이션 캐릭터들이 등장하는 생동감 있고 다채로운 일러스트입니다. 파란색 하늘 배경에 캐릭터들이 함께 서서 역동적이고 생동감 넘치는 장면을 연출하고 있습니다.

  1. 루피: 중앙에는 밀짚모자와 빨간 재킷을 입은 루피가 시리즈의 주인공입니다. 그는 초인적인 힘과 유연성을 주는 艅↑꺐?쒎츩(艅↑꺐?쒎츩) 또는 고무 과일로 유명합니다.
  2. 나미: 루피 오른쪽에는 긴 주황색 머리와 파란색 비키니 상의를 입은 나미가 그려져 있습니다. 그녀는 항해사이자 숙련된 항해사로, 바다에 대한 지식을 활용해 승무원들을 안내하는 모습을 자주 볼 수 있습니다.
  3. 조로: 루피의 왼쪽에 있는 조로는 초록색 머리와 초록색 재킷을 입은 검객입니다. 그는 세 개의 검과 세계에서 가장 강한 검객이 되겠다는 결단력으로 유명합니다.
  4. 산지**: 조로 옆에 있는 산지는 긴 금발 머리에 검은색 재킷을 입은 셰프입니다. 그는 요리 실력과 음식에 대한 애정으로 유명합니다.
  5. 초퍼: 산지 오른쪽에 있는 초퍼는 파란 모자와 빨간 코트를 입은 젊은 의사입니다. 그는 사이보그이자 밀짚모자 해적단의 일원입니다.
  6. 우솝: 초퍼 왼쪽에 있는 우솝은 녹색 머리와 녹색 재킷을 입은 사격 선수입니다. 그는 날카로운 사격 실력과 장난에 대한 애정으로 유명합니다.
  7. 토니 토니 초퍼: 우솝 왼쪽에 있는 토니 초퍼는 빨간 모자와 빨간 코트를 입은 사이보그입니다. 그는 의사이자 밀짚모자 해적단의 일원입니다.
  8. 프랭키: 토니 초퍼 오른쪽에 있는 프랭키는 파란색 모자와 파란색 재킷을 입은 사이보그입니다. 그는 기계 기술과 음악에 대한 사랑으로 유명합니다.
  9. 브룩: 프랭키 오른쪽에 있는 브룩은 흰색 모자와 흰색 코트를 입은 음악가입니다. 그는 밀짚모자 해적단의 일원이자 숙련된 음악가입니다.
  10. 보아 핸콕: 브룩 오른쪽에 있는 보아 핸콕은 긴 검은 머리와 파란 비키니 상의를 입은 힘차고 아름다운 여성입니다. 그녀는 힘과 해적 황후로서의 역할로 잘 알려져 있습니다.
  11. 베포: 행콕 왼쪽에 있는 베포는 빨간 모자와 빨간 코트를 입은 말하는 개입니다. 그는 밀짚모자 해적단의 일원이자 승무원들의 충성스러운 동반자입니다.
  12. 빅맘: 베포의 오른쪽에 있는 빅맘은 크고 빨간색이며 검은 몸을 가진 강력하고 무시무시한 해적입니다. 그녀는 엄청난 힘과 해적 황후로서의 역할로 유명합니다.

캐릭터들은 다양한 포즈로 묘사되어 있으며, 일부는 팔을 들어 흥분하거나 결단력 있게 움직이며 동료애와 모험심을 자아냅니다. 전체적인 장면은 활기차고 끾빨域삣뒟으로 ‘ 원피스’ 시리즈의 활기차고 모험적인 정신을 반영하고 있습니다.

베포는 누구? 빅맘은 없는 뎁쇼. 일단 그래도 대체로 정확? 한거 같아요?

./llama-mtmd-cli.exe -m ./Qwen2-VL-7B-Instruct-Q4_0.gguf --mmproj ./mmproj-Qwen2-VL-7B-Instruct-f32.gguf --image ./terrorist.jpg --temp 0.0 -p "Describe the given image closely. And don't make it up by saying with certainty that you don't know anything you don't know." -ngl 100 --n-gpu-layers 100

프롬프트와 창의성 지수를 조금 수정해 봤어요.

The image shows a person wearing glasses and a white shirt. The person is holding a microphone close to their mouth, suggesting that they are speaking or singing into it. The background is dark, which makes the person and the microphone stand out. The person appears to be in a recording studio or a similar environment.

이미지에는 안경을 쓰고 흰색 셔츠를 입은 사람의 모습이 담겨 있습니다. 이 사람은 마이크를 입 가까이 대고 있어 말을 하거나 노래를 부르고 있음을 알 수 있습니다. 배경이 어두워서 사람과 마이크가 눈에 띕니다. 이 사람은 녹음실이나 비슷한 환경에 있는 것으로 보입니다.

The image appears to be a screenshot from a video game, likely a first-person shooter. The player is holding a large, futuristic-looking weapon with a large barrel and a scope. The weapon is pointed towards a distant objective, which is marked by a blue flag. The game interface includes various elements such as a minimap on the left side, a health and armor bar at the top, and a scoreboard on the right side. The environment is a desert-like landscape with rocky terrain and a few palm trees. There are also some structures in the background, possibly buildings or fortifications. The game appears to be in progress, with the player actively engaged in the game.

이 이미지는 비디오 게임의 스크린샷으로 보이며, 1인칭 슈팅 게임일 가능성이 높습니다. 플레이어는 큰 배럴과 스코프가 달린 미래지향적으로 보이는 커다란 무기를 들고 있습니다. 무기는 파란색 깃발로 표시된 먼 물체를 향하고 있습니다. 게임 인터페이스에는 왼쪽의 미니맵, 상단의 체력 및 갑옷 막대, 오른쪽의 스코어보드 등 다양한 요소가 포함되어 있습니다. 환경은 바위 지형과 몇 그루의 야자수가 있는 사막과 같은 풍경입니다. 배경에는 건물이나 요새 같은 구조물도 있습니다. 플레이어가 게임에 적극적으로 참여하는 등 게임이 진행 중인 것으로 보입니다.

PS Q:\llama.cpp\build\bin\Release> ./llama-simple-chat -m llama-3-Korean-Bllossom-8B-Q4_K_M.gguf -c 2048
……………………………………………………………………………
> 안녕하세유
?덈뀞?섏꽭?? 臾댁뾿???꾩??쒕┫源뚯슂?
> hello?
Hello! How can I help you today?
> how are you feeling today?
I’m just an AI, I don’t have feelings like humans do, but I’m functioning properly and ready to help with any questions or tasks you have! How about you?
> how can i chat with you with korean?
?? ?쒓뎅?대줈 ??뷀븷 ???덉뼱?? ?쒓뎅?대줈 吏덈Ц?섍굅????붾? 二쇨퀬諛쏆쓣 ???덉뒿?덈떎. ?대뼡 二쇱젣濡??댁빞湲곕? ?쒖옉?섍퀬 ?띠쑝?좉???
> winodws powershell’s encoding does not allow korean text
Powershell??湲곕낯 ?몄퐫???ㅼ젙 ?뚮Ц???쒓????쒕?濡??쒖떆?섏? ?딅뒗 臾몄젣媛 諛쒖깮?섎뒗 寃?媛숈븘?? Powershell?먯꽌 ?쒓????ъ슜???뚮뒗 UTF-16LE ?몄퐫?⑹쓣 ?ъ슜?섎뒗 寃껋씠 醫뗭뒿?덈떎. ???ㅼ젙???곸슜?섎뒗 諛⑸쾿? ?ㅼ쓬怨?媛숈뒿?덈떎:

1. Powershell??愿由ъ옄 沅뚰븳?쇰줈 ?ㅽ뻾?⑸땲??
2. ?ㅼ쓬 紐낅졊?대? ?낅젰?섏뿬 UTF-16LE ?몄퐫?⑹쓣 ?ъ슜?섎룄濡??ㅼ젙?⑸땲??
“`powershell
$OutputEncoding = [System.Text.Encoding]::UTF16LE
[System.Console]::OutputEncoding = $OutputEncoding
“`
3. ??紐낅졊?대? ?ㅽ뻾???? Powershell 李쎌뿉???쒓????낅젰?섍굅??異쒕젰?????덉뒿?덈떎.

???ㅼ젙???듯빐 Powershell?먯꽌 ?쒓????뺤긽?곸쑝濡??ъ슜?????덉쓣 寃껋엯?덈떎.
>

잘되네요 다만 powershell환경의 인코딩 문제로 인해 한글이 출력이 안됩니다.

# 입력/출력 인코딩을 UTF-8로 설정
[System.Console]::InputEncoding = [System.Text.Encoding]::UTF8
[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# 로케일 설정 (C.UTF-8: UTF-8 기반 C 로케일)
$env:LC_ALL = 'C.UTF-8'

# 변경 확인
[System.Console]::OutputEncoding
$env:LC_ALL

위와 같이 설정하면

잘되지롱

> c++로 오목게임 만들어줘용
C++로 오목 게임을 만드는 것은 비교적 복잡한 프로젝트입니다. 하지만, 기본적인 구조를 이해하고, 단순한 게임을 시작하는 데 도움을 줄 수 있는 예제 코드를 제공해 드릴 수 있습니다. 이 예제는 콘솔 프로그램으로, 사용자 간의 게임을 구현합니다. 게임의 규칙은 다음과 같습니다:

- 사용자는 1번부터 9번까지의 숫자를 입력하여 구체적인 위치에 돌을 놓을 수 있습니다.
- 두 개의 돌이 서로 마주치면, 그 위치는 다시 빈 공간으로 설정됩니다.

코드 예제는 다음과 같습니다:
```cpp
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int SIZE = 3; // 보드의 크기
const int TOTAL_CELLS = SIZE * SIZE; // 보드의 총 셀 개수

// 보드 초기화
char board[SIZE][SIZE] = {{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
char currentPlayer = 'X'; // 현재 플레이어 (X 또는 O)

void printBoard() {
    cout << " 1 | 2 | 3" << endl;
    cout << "  ---------" << endl;
    cout << " 4 | 5 | 6" << endl;
    cout << "  ---------" << endl;
    cout << " 7 | 8 | 9" << endl;
}

bool isValidMove(int move) {
    return move >= 1 && move <= TOTAL_CELLS;
}

void makeMove(int move) {
    if (!isValidMove(move)) {
        cout << "잘못된 입력입니다. 다시 시도해 주세요." << endl;
        return;
    }

    int row = (move - 1) / SIZE;
    int col = (move - 1) % SIZE;

    if (board[row][col] == 'X' || board[row][col] == 'O') {
        cout << "이미 차식이 있습니다. 다른 위치를 선택해 주세요." << endl;
        return;
    }

    board[row][col] = currentPlayer;
    cout << "돌을 " << move << "위치에 놓았습니다." << endl;
}

bool hasWon() {
    // horizontal
    for (int i = 0; i < SIZE; i++) {
        if (board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
            return true;
        }
    }
    // vertical
    for (int i = 0; i < SIZE; i++) {
        if (board[0][i] == board[1][i] && board[1][i] == board[2][i])) {
            return true;
        }
    }
    // diagonal
    if ((board[0][0] == board[1][1] && board[1][1] == board[2][2]) ||
         (board[0][2] == board[1][1] && board[1][1] == board[2][0])) {
        return true;
    }
    return false;
}

bool isDraw() {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (board[i][j] != 'X' && board[i][j] != 'O') {
                return false;
            }
        }
    }
    return true;
}

int main() {
    srand(time(0)); // 랜덤 시드

    while (true) {
        printBoard();
        int move;
        cout << currentPlayer << "'s turn. 입력하세요: ";
        cin >> move;
        makeMove(move);

        if (hasWon()) {
            printBoard();
            cout << currentPlayer << " wins!" << endl;
            break;
        } else if (isDraw()) {
            printBoard();
            cout << "무승부입니다." << endl;
            break;
        }

        // 다음 플레이어 설정
        currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
    }

    return 0;
}
```
이 코드는 간단한 오목 게임의 기본 구조를 제공합니다. 플레이어가 돌을 놓을 위치를 입력할 때까지 게임을 진행합니다. 게임이 끝나면 승리자나 무승부 여부를 출력합니다.

이 코드를 실행하면, 사용자는 숫자를 입력하여 돌을 놓을 수 있습니다. 예를 들어, 5를 입력하면 5위치에 'X' 또는 'O'가 놓이게 됩니다.

이 예제는 매우 기본적인 구조입니다. 실제 게임을 완성하는 데는 더 많은 기능과 논리적인 부분이 필요합니다. 예를 들어, 게임이 끝나지 않았을 때 다시 돌을 놓을 수 있는 기능, 더 복잡한 승리 조건, 그래픽 인터페이스 등이 추가될 수 있습니다.

뭐 대충 동작은 하는 듯? 하네용

좋아요

./llama-minicpmv-cli -m ./ggml-model-Q4_K_M.gguf --mmproj ./mmproj-model-f16.gguf -c 4096 --temp 0.7 --top-p 0.8 --top-k 100 --repeat-penalty 1.05 --video video_test.mp4  -p "What is in the video?"

video understanding도 되는 모양이다.

https://medium.com/@bSharpML/use-llamaindex-and-a-local-llm-to-summarize-youtube-videos-29817440e671

https://github.com/byjlw/video-analyzer

아직은 여러 방면으로 무리일지도…