![見出し画像](https://assets.st-note.com/production/uploads/images/172248145/rectangle_large_type_2_453acfbd7c46fd9b799fbb7aa6fe5e5b.png?width=1200)
WSL2でDeepSeek-R1(1.58bit)をllama.cppで試してみる
DeepSeek-R1の1.58bitモデルを、VRAMに乗りきらないことは分かった上で、RTX 4090(24GB)で試してみます。
使用するPCはドスパラさんの「GALLERIA UL9C-R49」。スペックは
・CPU: Intel® Core™ i9-13900HX Processor
・Mem: 64 GB
・GPU: NVIDIA® GeForce RTX™ 4090 Laptop GPU(16GB)・GPU: NVIDIA® GeForce RTX™ 4090 (24GB) ※外付け
・OS: Ubuntu22.04 on WSL2(Windows 11)
です。
1. llama.cppのセットアップ
llama.cppをセットアップして試します。
リポジトリをクローンします。
git clone https://github.com/ggerganov/llama.cpp.git
cd llama.cpp
CUDA使用をON、HuggingFaceからのダウンロードを可能にするためCURL使用もONにして、makeします。
cmake -B build -DBUILD_SHARED_LIBS=OFF -DGGML_CUDA=ON -DLLAMA_CURL=ON
cmake --build build --config Release -j --clean-first
モデルのダウンロード
必要なパッケージをインストールしてから、
pip install huggingface_hub hf_transfer
pythonコマンドを叩いて以下を流し込みます。約140GBなのでしばし待ち待ちます。
from huggingface_hub import snapshot_download
snapshot_download(
repo_id = "unsloth/DeepSeek-R1-GGUF",
local_dir = "DeepSeek-R1-GGUF",
allow_patterns = ["*UD-IQ1_S*"], # Select quant type UD-IQ1_S for 1.58bit
)
2. 試してみる
llama-cliコマンドを使用します。
CUDA_VISIBLE_DEVICES=0 ./build/bin/llama-cli \
--model DeepSeek-R1-GGUF/DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
--cache-type-k q4_0 \
--threads 12 -no-cnv --prio 2 \
--n-gpu-layers 7 \
--temp 0.6 \
--ctx-size 8192 \
--seed 3407 \
--prompt "<|User|>Create a Flappy Bird game in Python.<|Assistant|>"
RTX 4090(24GB) 1枚で動作させるために、--n-gpu-layersオプションの設定値を調整します。
(1) --n-gpu-layers 7
62レイヤーのうち7レイヤーをロードしています。
load_tensors: offloading 7 repeating layers to GPU
load_tensors: offloaded 7/62 layers to GPU
load_tensors: CPU_Mapped model buffer size = 47058.04 MiB
load_tensors: CPU_Mapped model buffer size = 47109.49 MiB
load_tensors: CPU_Mapped model buffer size = 23859.37 MiB
load_tensors: CUDA0 model buffer size = 15703.16 MiB
![](https://assets.st-note.com/img/1738308416-mp6djl8OXyz4J7Df0R3GAuPM.png)
(2) --n-gpu-layers 8
こちらは8レイヤーをロード。
load_tensors: offloading 8 repeating layers to GPU
load_tensors: offloaded 8/62 layers to GPU
load_tensors: CPU_Mapped model buffer size = 47058.04 MiB
load_tensors: CPU_Mapped model buffer size = 47109.49 MiB
load_tensors: CPU_Mapped model buffer size = 21616.06 MiB
load_tensors: CUDA0 model buffer size = 17946.47 MiB
![](https://assets.st-note.com/img/1738205889-IPWwrJHji9S0XRcuLG14hZTp.png)
(3) 応答結果
プロンプトが以下。
Create a Flappy Bird game in Python.
応答がこちら。動きはしましたが、当然遅いです。
<think>
Okay, the user wants me to create a Flappy Bird game in Python. Hmm, I need to think about how to approach this. Let's start by breaking down the problem. Flappy Bird is a simple game where a bird flies between pipes, and the player taps to make the bird jump. So, the key components are the bird, pipes, scoring, and collision detection.
First, I should choose a Python library for graphics and user input. I remember that Pygame is a good library for creating games. It handles graphics, sound, and events. So I'll use Pygame.
Next, let's outline the main components needed:
1. The bird that can fall due to gravity and jump when the user presses a key.
2. Pipes that move from the right side of the screen. They should come in pairs with a gap, and the player has to navigate through them.
3. A scoring system where each time the bird passes a pair of pipes, the score increases.
4. Collision detection for when the bird hits the ground, ceiling, or a pipe.
5. Game loop that handles updates and rendering.
Starting with initializing Pygame. I'll need to set up the display window, set the caption, and create a clock for controlling the frame rate.
The bird needs to have gravity. So, the bird's y position will change with a velocity that increases due to gravity each frame. When the user presses a key (like space or up arrow), the velocity decreases, making the bird rise.
For the pipes, I'll need a mechanism to spawn them at certain intervals, say every 1500 milliseconds. They should move from the right to the left. Each pipe pair has an upper and lower part with a gap. The gap's position should be random within a range to make the game challenging.
Collision detection is critical. The bird has a rectangle, and each pipe has a rectangle. Check for collisions between the bird and any pipe. Also, check if the bird hits the ground or the top of the screen.
Scoring: Whenever a pipe pair's x position is such that the bird has passed it (maybe when the pipe's right edge is left of the bird's left edge), increment the score.
Now, about the code structure. The main loop will handle events, update game state, and render everything each frame.
Possible steps:
1. Initialize Pygame, set up the window.
2. Create classes for Bird and Pipe.
3. Handle events: check for key presses to make the bird jump.
4. In the game loop, update the bird's position based on velocity and gravity.
5. Spawn new pipes at intervals, move existing pipes leftwards.
6. Check for collisions. If collision occurs, end the game.
7. Draw all elements (bird, pipes, score) each frame.
8. Update the display and manage the frame rate with the clock.
Let me think about the Bird class. It should have an image or a shape. Maybe a rectangle for simplicity. The bird's position (x, y) and velocity (vertical speed). Each frame, velocity increases by gravity, y position increases by velocity. When the user presses a key, apply a negative velocity (like a jump).
For the pipes: Each pipe pair has a top and bottom pipe. The gap between them is fixed, but their positions are random. Each pipe is a rectangle. They move leftward. Once they go off-screen, they can be removed.
I need to manage the pipes in a list. Every certain time, add a new pair. Then, in each frame, move them left and check for collision.
The score is increased each time the bird passes a pipe pair. How to detect that? Maybe when the pipe's x position is less than the bird's x position (but need to check once per pipe pair to avoid multiple increments). So, track each pipe pair and check if the bird has passed it.
Now, code outline:
- Import pygame and necessary modules.
6. Set up the game window, clock, etc.
- Define constants like GRAVITY, BIRD_JUMP, pipe speed, etc.
? Maybe GRAVITY = 0.7, BIRD_JUMP = -5.5 (velocity change).
- Create Bird class with update and draw methods.
- Create Pipe class or manage pipes with functions.
- Main loop: handling events, updating, rendering.
Possible code steps:
Initialize Pygame:
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()
Bird variables: x, y, velocity. Maybe start in the middle.
Pipes: list of pipe pairs. Each pair has top and bottom pipes, with a gap.
In the game loop:
- Check for events: if space or up key pressed, bird jumps (velocity = BIRD_JUMP).
% Maybe event.get() to check for keydown events.
Update bird position: velocity += GRAVITY, y += velocity.
Spawn pipes: use a timer, maybe a variable that counts down each frame. When it reaches zero, add a new pipe pair.
Move pipes: for each pipe in the list, move their x by a certain amount (like -3 per frame). Remove pipes that are off-screen.
Check collision: for each pipe, check if bird's rect collides with pipe's rect. Also check if bird hits the ground (y >= screen height) or goes above the screen.
Score: when the bird's x is past the pipe's x (maybe using a separate check for each pipe pair once).
Drawing: draw the bird, pipes, and display the score.
Handling game over: when collision, reset the game or show a message.
Possible code:
But let's start writing the code step by step.
First, constants:
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
BIRD_JUMP = -8
GRAVITY = 0.6
PIPE_SPEED = 3
PIPE_SPAWN_INTERVAL = 1500 # milliseconds
Bird class:
class Bird:
def __init__(self):
self.x = SCREEN_WIDTH // 4
self.y = SCREEN_HEIGHT // 2
self.velocity = 0
# Rect for collision
self.rect = pygame.Rect(self.x, self.y, 30, 30) # size 30x30
def update(self):
self.velocity += GRAVITY
self.y += self.velocity
self.rect.y = self.y
# Check boundaries
if self.y < 0:
self.y = 0
if self.y + 30 > SCREEN_HEIGHT:
self.y = SCREEN_HEIGHT - 30
def jump(self):
self.velocity = BIRD_JUMP
Pipes: need to generate pairs. Each pair has a top and bottom pipe. The vertical position of the gap is random.
So, define a Pipe class or generate pipes as a list of dictionaries.
But perhaps a function to generate a pipe pair.
Each pipe pair has a top and bottom pipe, each with a rectangle.
For example:
def create_pipe():
gap_y = random.randint(100, SCREEN_HEIGHT - 300)
gap_height = 150
top_pipe = pygame.Rect(SCREEN_WIDTH, 0, 50, gap_y)
bottom_pipe = pygame.Rect(SCREEN_WIDTH, gap_y + gap_height, 50, SCREEN_HEIGHT - (gap_y + gap_height))
return (top_pipe, bottom_pipe)
But then, each pipe pair is a list of two rectangles.
In the game, we can have a list of pipe pairs, each with their positions.
In the main loop:
bird = Bird()
pipes = []
spawn_counter = 0 # or use event to spawn pipes every interval.
But handling timing in Pygame can be done with a timer event.
Alternatively, use a cooldown, like every 1500 milliseconds, but in frames, it's better to use a timer event.
So, in Pygame, we can create a custom event for pipe spawning.
But maybe for simplicity, in the main loop, track the time since the last pipe was spawned, and when the elapsed time exceeds the interval, spawn a new pipe.
In the game loop:
current_time = pygame.time.get_ticks()
if current_time - last_spawn > PIPE_SPAWN_INTERVAL:
create a new pipe pair and add to pipes list.
But perhaps using a timer event: set a USEREVENT to spawn pipes.
In the code:
pygame.time.set_timer(PIPE_SPAWN_EVENT, PIPE_SPAWN_INTERVAL)
But for the code, perhaps in the event loop, check if the event is the spawn event and then add pipes.
Alternatively, track the time each frame and spawn pipes accordingly.
Either way.
Now, collision detection: for each pipe pair in the pipes list, check if the bird's rect collides with either the top or bottom pipe.
Also, check if the bird is touching the ground (y + height > SCREEN_HEIGHT) or flying off the top (y < 0).
Scoring: each time a pipe pair has moved past the bird, increment the score. So, perhaps track for each pipe pair if the bird has passed it. Once passed, increase the score and don't check again for that pipe.
Alternatively, when the pipe's right edge is to the left of the bird's left edge, and it hasn't been counted yet.
But perhaps, in each pipe pair, track if it has been passed. So, when the pipe's x is less than the bird's x, and hasn't been counted, increment the score.
But this can be more complex.
Alternatively, for each pipe pair, when the pipe's x is less than bird.x, and hasn't been counted, then score += 1.
But since the pipes are moving left, when they pass the bird's position, the score increases.
But to avoid counting the same pipe multiple times, each pipe pair should be marked as passed once.
So, perhaps for each pipe in the list, when it's x is less than bird.x - 30 (bird's width), and it hasn't been counted, then increment the score and mark it as counted.
But how to structure that.
Alternatively, for each pipe pair, check if the bird's x is greater than the pipe's x + width, then score += 1, and remove that pipe from the list. Wait, perhaps not.
Alternatively, have a list of pipes, and when a pipe's right edge is to the left of the bird's left edge, then the score increases, and that pipe can be removed or marked as passed.
But perhaps the easiest way is to track the pipes and for each pipe pair, when the bird's x is greater than the pipe's x (since pipes are moving left), and it's not yet passed, then score +=1.
But how to implement that.
This could get a bit tricky. Maybe for each pipe pair, check if it's the first time the bird has passed it, and if so, increase the score.
In code:
for pipe_pair in pipes:
if pipe_pair.right < bird.rect.left and not pipe_pair.passed:
score += 1
pipe_pair.passed = True
But then each pipe pair would need a 'passed' attribute.
Alternatively, since the pipes are moving left, their x positions are decreasing. So for each pipe, when their x is less than bird.x - pipe_width, increment score.
But perhaps the simplest is to have a list of pipes, and when a pipe's x is behind the bird's x (considering their positions), and that pipe hasn't been counted, then score +=1.
But this could require tracking each pipe's status.
So, perhaps each pipe pair is an object with top and bottom pipes, x position, and a 'passed' flag.
But to keep it simple, perhaps in code, each pipe pair is a tuple of top and bottom rects, and their x is moving left. So when the bird's x is past the pipe's x, then score increases.
But since the bird is moving right? Wait, no. The bird's x is fixed? Or is the bird moving?
Wait, in the original Flappy Bird, the bird is in the same x position (like centered), and the pipes move from the right to left. So the bird isn't moving forward, the pipes move towards the bird.
So, in this case, the bird's x is fixed, and the pipes move left. So when a pipe pair's right edge is to the left of the bird's left edge, that means the bird has passed through the gap.
Wait, but the pipes are moving left, so the bird is stationary in the x-axis, and the pipes move towards the left.
Therefore, the bird's x is fixed, and the pipes move left past the bird.
Therefore, when a pipe's right edge is to the left of the bird's left edge, and it hasn't been counted yet, the score increases.
So, in code:
for pipe in pipes:
if pipe.right < bird.rect.left and not pipe.passed:
score += 1
pipe.passed = True
But how to model the pipe's right edge. Each pipe pair has a top and bottom pipe, but both are part of the same pair. So perhaps each pipe pair is a group with a top and bottom, and their x positions.
Wait, maybe each pipe pair is represented by their top and bottom, but for scoring, once either of them has passed the bird, but since they are part of the same pair, it's better to consider the pair as passed when both have moved past.
Alternatively, since the pipes are moving left, the entire pair moves together, so checking the position of the top pipe (since all are moving left) would suffice.
But perhaps this is getting too complicated. Let's think differently.
Each pipe pair is generated at the right edge of the screen. The top pipe's bottom is at a certain Y, and the bottom pipe's top is at Y + gap. The gap is a fixed height, so the bird has to pass through that gap.
But for scoring, when the pipe pair has moved past the bird.
So, perhaps we can model each pipe pair as a single object with an x position. So each pipe pair has a top and bottom, and their x position. As the x decreases (moves left), when the x + width is less than the bird's x, then the bird has passed through.
But perhaps each pipe pair's x is the x of the top pipe. Then, when the pipe's x is less than the bird's x, and hasn't been passed, then score +=1.
But this would require tracking each pipe pair's passed status.
Alternatively, for simplicity, since each pipe pair is added to the list, and when the pipe pair's x (the leftmost x of the pipe pair) is less than the bird's x, and hasn't been passed, then score increases.
But perhaps in code:
for pipe_pair in pipes:
top_pipe, bottom_pipe = pipe_pair
if top_pipe.right < bird.rect.left and not pipe_pair.passed:
score += 1
pipe_pair.passed = True
But in this case, each pipe pair would need to have a 'passed' attribute.
Alternatively, track separately which pipes have been passed.
But perhaps in this code, we can manage the pipes as a list of pipe pairs, each consisting of top and bottom rectangles.
So, in code:
pipes = [] # list of pipe pairs, each pair is [top_rect, bottom_rect]
When spawning a new pipe pair:
top_pipe = pygame.Rect(SCREEN_WIDTH, 0, 50, height)
bottom_pipe = pygame.Rect(SCREEN_WIDTH, height + gap, 50, SCREEN_HEIGHT - (height + gap))
Then, each frame, move the pipes to the left:
for pipe_pair in pipes:
pipe_pair[0].x -= PIPE_SPEED
pipe_pair[1].x -= PIPE_SPEED
But this would be for each pipe pair's top and bottom.
Then, collision detection: check for bird's rect colliding with pipe_pair's top or bottom.
But in Pygame, you can check for collisions between the bird's rect and each pipe's rect.
So:
for pipe_pair in pipes:
if bird.rect.colliderect(pipe_pair[0]) or bird.rect.colliderect(pipe_pair[1]):
game_over = True
Also, check if the bird hits the ground (bird.rect.bottom >= SCREEN_HEIGHT) or the top (bird.rect.top <= 0).
Now, putting it all together.
The code:
- Initialize Pygame, set the screen.
) Create the bird as a class instance.
- In the game loop, handle events (quit, key down for jump).
- Update bird position each frame.
" Spawn pipes at intervals.
- Move pipes each frame.
- Check for collisions.
- Draw everything.
Now, writing the code.
But wait, the user said "create a Flappy Bird game in Python". So, the code needs to be complete.
Potential code:
import pygame
import random
# Initialize Pygame
pygame.init()
# Screen dimensions
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Flappy Bird")
# Clock for controlling the frame rate
clock = pygame.time.Clock()
# Bird properties
BIRD_JUMP = -8
GRAVITY = 0.5
PIPE_SPEED = 3
PIPE_SPAWN_INTERVAL = 1500 # milliseconds
PIPE_WIDTH = 50
PIPE_GAP = 150
# Bird class
class Bird:
def __init__(self):
self.x = SCREEN_WIDTH // 4
self.y = SCREEN_HEIGHT // 2
self.velocity = 0
self.rect = pygame.Rect(self.x, self.y, 30, 30) # 30x30 square
def update(self):
self.velocity += GRAVITY
self.y += self.velocity
self.rect.y = self.y
# Keep the bird within the screen
if self.rect.top < 0:
self.rect.top = 0
self.velocity = 0
if self.rect.bottom > SCREEN_HEIGHT:
self.rect.bottom = SCREEN_HEIGHT
self.velocity = 0
def jump(self):
self.velocity = BIRD_JUMP
# Pipe generation
def create_pipe():
gap_position = random.randint(100, SCREEN_HEIGHT - 200)
top_pipe = pygame.Rect(SCREEN_WIDTH, 0, PIPE_WIDTH, gap_position)
bottom_pipe = pygame.Rect(SCREEN_WIDTH, gap_position + PIPE_GAP, PIPE_WIDTH, SCREEN_HEIGHT - (gap_position + PIPE_GAP))
return (top_pipe, bottom_pipe)
# Game variables
bird = Bird()
pipes = []
score = 0
game_over = False
last_spawn = pygame.time.get_ticks()
font = pygame.font.Font(None, 36)
# Main loop
running = True
while running:
# Handle events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and not game_over:
bird.jump()
if event.type == pygame.USEREVENT + 1: # Pipe spawn event
pipes.append(create_pipe())
# Spawn pipes
current_time = pygame.time.get_ticks()
if current_time - last_spawn > PIPE_SPAWN_INTERVAL:
pipes.append(create_pipe())
last_spawn = current_time
if not game_over:
# Update bird
bird.update()
# Move pipes
for pipe_pair in pipes:
pipe_pair[0].x -= PIPE_SPEED
pipe_pair[1].x -= PIPE_SPEED
# Remove off-screen pipes
pipes = [pipe_pair for pipe_pair in pipes if pipe_pair[0].x > -PIPE_WIDTH]
# Check collisions
for pipe_pair in pipes:
if bird.rect.colliderect(pipe_pair[0]) or bird.rect.colliderect(pipe_pair[1]):
game_over = True
if bird.rect.bottom >= SCREEN_HEIGHT or bird.rect.top <= 0:
game_over = True
# Update score
for pipe_pair in pipes:
if pipe_pair[0].x + PIPE_WIDTH < bird.rect.left and not hasattr(pipe_pair, 'passed'):
score += 1
pipe_pair.passed = True
# Draw everything
screen.fill((0, 0, 0)) # Black background
# Draw bird
pygame.draw.rect(screen, (255, 0, 0), bird.rect)
# Draw pipes
for pipe_pair in pipes:
pygame.draw.rect(screen, (0, 255,2), pipe_pair[0])
pygame.draw.rect(screen, (0, 255, 0), pipe_pair[1])
# Draw score
score_text = font.render(f"Score: {score}", True, (255, 255, 255))
screen.blit(score_text, (10, 10))
if game_over:
game_over_text = font.render("Game Over!", True, (255, 255, 255))
screen.blit(game_over_text, (SCREEN_WIDTH//2 - 100, SCREEN_HEIGHT//2 - 20))
pygame.display.update()
clock.tick(60)
pygame.quit()
Wait, but there are a few issues here.
First, the pipe spawn event: in the code, the event is checked, but I set a USEREVENT. Alternatively, using a timer.
In the code, the event loop checks for USEREVENT + 1, which may not be set. So perhaps the code should use pygame.time.set_timer to fire an event when it's time to spawn a pipe.
But in the current code, the spawn is handled by checking the current time against the last spawn time. That's more straightforward.
But in the code above, after handling events, the code checks if the current time minus last_spawn is greater than the interval, then spawns a pipe and updates last_spawn.
That's better because it's more straightforward and doesn't require handling custom events.
So, in the main loop:
current_time = pygame.time.get_ticks()
if current_time - last_spawn >= PIPE_SPAWN_INTERVAL:
pipes.append(create_pipe())
last_spawn = current_time
Yes, that's the way.
Another issue: when checking for passed pipes, the code tries to check if the pipe's x + width is less than bird's left, and then increments the score. But the way it's handled in the code:
for pipe_pair in pipes:
if pipe_pair[0].x + PIPE_WIDTH < bird.rect.left and not hasattr(pipe_pair, 'passed'):
But wait, each pipe_pair is a tuple of two rects. Adding a 'passed' attribute to a tuple is not possible. So that's a problem.
Thus, perhaps the code needs to track which pipes have been passed. So, maybe each pipe_pair should be a dictionary or an object that has a 'passed' attribute.
But to keep it simple, perhaps track the pipes in a list, and for each pipe pair, when the pipe's x is less than bird's x, and not yet passed, increment score.
But how to track that. Since the pipe_pair is a tuple of rects, perhaps we can track a separate list of passed statuses. Alternatively, create a list of pipe pairs, each being a dictionary with 'top', 'bottom', and 'passed'.
But that complicates things. Alternatively, when the pipe's x + width is less than the bird's x, then score increments. But since the pipes are moving left, the pipe's right edge (x + width) moving past the bird's left edge (bird.rect.left) would be the condition.
But since the bird's x is fixed (since the bird doesn't move left or right), each pipe pair's top pipe's x (which starts at SCREEN_WIDTH) moves left. So when the pipe's right edge (x + width) is less than the bird's x, then the bird has passed through.
But since the bird is at SCREEN_WIDTH // 4 (maybe x = 200 if screen width is 800), then when the pipe's right edge is less than 200, the bird has passed.
But the code's bird's x is fixed (SCREEN_WIDTH // 4). So in the code, bird.rect.left is bird.x (which is 200).
So, for each pipe pair, check if the top pipe's x plus width is less than bird's x (200). If so, increment the score.
But since each pipe pair is added to the list, and moved left each frame, we need to check for each pipe pair once. But how to track that.
But in the code above, the code does:
for pipe_pair in pipes:
if pipe_pair[0].x + PIPE_WIDTH < bird.rect.left and not hasattr(pipe_pair, 'passed'):
score +=1
pipe_pair.passed = True
But pipe_pair is a tuple, so adding an attribute isn't possible. So this approach won't work.
Alternative approach: track the pipes as a list of dictionaries, each with 'top', 'bottom', and 'passed' keys.
So, when creating a pipe pair:
def create_pipe():
gap_position = random.randint(100, SCREEN_HEIGHT - 200)
top_pipe = pygame.Rect(SCREEN_WIDTH, 0, PIPE_WIDTH, gap_position)
bottom_pipe = pygame.Rect(SCREEN_WIDTH, gap_position + PIPE_GAP, PIPE_WIDTH, SCREEN_HEIGHT - (gap_position + PIPE_GAP))
return {'top': top_pipe, 'bottom': bottom_pipe, 'passed': False}
Then, in the main loop:
for pipe in pipes:
if pipe['top'].x + PIPE_WIDTH < bird.rect.left and not pipe['passed']:
score +=1
pipe['passed'] = True
But in this case, each pipe is a dictionary, which allows storing the passed status.
So, in code:
Modify create_pipe to return a dictionary.
Then, in the code, when moving pipes:
for pipe in pipes:
pipe['top'].x -= PIPE_SPEED
pipe['bottom'].x -= PIPE_SPEED
Then, when checking for passed:
for pipe in pipes:
if pipe['top'].x + PIPE_WIDTH < bird.rect.left and not pipe['passed']:
score += 1
pipe['passed'] = True
This would correctly track each pipe pair once.
So, modifying the code accordingly.
Also, in the code, when creating a pipe, the gap_position should be such that the pipe doesn't go off the screen. For example, the gap_position could range between 100 and SCREEN_HEIGHT -
200, leaving enough space for the gap.
But perhaps that's correct.
Another thing: the bird's jump. When the user presses space or up arrow, the bird's velocity is set to BIRD_JUMP. So in the event loop, check for keydown events.
But in the code, the event loop checks for KEYDOWN events, and if the key is space and game is not over, then bird.jump().
That's correct.
Now, collision detection: when the bird's rect collides with any pipe, or hits the ground or ceiling, game_over is set to True.
But in the code, after moving the bird, it checks if bird.rect.bottom >= SCREEN_HEIGHT or top <= 0, then game_over.
Also, check for collisions with pipes.
In the code:
if not game_over:
# Update bird
# Move pipes
# Check collisions
for pipe in pipes:
if bird.rect.colliderect(pipe['top']) or bird.rect.colliderect(pipe['bottom']):
game_over = True
# Check ground/ceiling collision
if bird.rect.bottom >= SCREEN_HEIGHT or bird.rect.top <= 0:
game_over = True
But in the code, after moving the pipes and bird, the code checks for collision with each pipe.
But how the code is structured.
But perhaps the code has:
if not game_over:
bird.update()
move pipes
check for collisions with pipes
check for ground/ceiling
Thus, that's correct.
Now, rendering:
The bird is a red rectangle.
The pipes are green rectangles.
The score is white text.
Game over message is displayed when game_over is True.
So, the code draws all that.
Putting all together, the code should now work.
Testing the code:
The bird starts in the middle. The user presses space to make it jump. Pipes come from the right, moving left. The bird must navigate through the gaps. Each passed pipe increments the score. Collision with pipes or edges ends the game.
Possible issues:
- The pipes may not spawn correctly.
- The collision detection might be off.
- The score increment might be incorrect.
But in the code, the pipe spawning is handled by checking the current time against the interval, and adding a new pipe pair to the list.
Each pipe pair is a dictionary with top and bottom rects, and a 'passed' flag.
When the pipe's top x + width is less than bird's left x, and 'passed' is False, score increments.
Testing this code.
But let's write the code with these adjustments.
</think>
こちら5時間ほど経過して、閉じタグ</think>がやっと出てきました。
thinkタグ以降の回答がこちら。
To create a Flappy Bird game in Python, we'll use the Pygame library for graphics and event handling. Here's a structured approach and the complete code:
### Approach
1. **Initialize Pygame**: Set up the display, clock, and game window.
2. **Bird Mechanics**: The bird falls under gravity and jumps when a key is pressed. The bird's position and velocity are updated each frame.
3. **Pipes Generation**: Pipes spawn at intervals and move leftwards. Each pipe pair has a random vertical gap.
4. **Collision Detection**: Check if the bird collides with pipes, the ground, or the ceiling.
5. **Score Tracking**: Increment the score each time the bird passes a pipe pair.
6. **Game Loop**: Handle events, update game state, render elements, and manage frame rate.
### Complete Code
```python
import pygame
import random
# Initialize Pygame
pygame.init()
# Screen dimensions
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Flappy Bird")
# Clock for controlling the frame rate
clock = pygame.time.Clock()
# Bird properties
BIRD_JUMP = -8
GRAVITY = 0.5
PIPE_SPEED = 3
PIPE_SPAWN_INTERVAL = 1500 # milliseconds
PIPE_WIDTH = 50
PIPE_GAP = 150
# Bird class
class Bird:
def __init__(self):
self.x = SCREEN_WIDTH // 4
self.y = SCREEN_HEIGHT // 2
self.velocity = 0
self.rect = pygame.Rect(self.x, self.y, 30, 30) # 30x30 square
def update(self):
self.velocity += GRAVITY
self.y += self.velocity
self.rect.y = self.y
# Keep the bird within the screen
if self.rect.top < 0:
self.rect.top = 0
self.velocity = 0
if self.rect.bottom > SCREEN_HEIGHT:
self.rect.bottom = SCREEN_HEIGHT
self.velocity = 0
def jump(self):
self.velocity = BIRD_JUMP
# Pipe generation
def create_pipe():
gap_position = random.randint(100, SCREEN_HEIGHT - 200)
top_pipe = pygame.Rect(SCREEN_WIDTH, 0, PIPE_WIDTH, gap_position)
bottom_pipe = pygame.Rect(SCREEN_WIDTH, gap_position + PIPE_GAP, PIPE_WIDTH, SCREEN_HEIGHT - (gap_position + PIPE_GAP))
return {'top': top_pipe, 'bottom': bottom_pipe, 'passed': False}
# Game variables
bird = Bird()
pipes = []
score = 0
game_over = False
last_spawn = pygame.time.get_ticks()
font = pygame.font.Font(None, 36)
# Main loop
running = True
while running:
# Handle events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and not game_over:
bird.jump()
# Spawn pipes
current_time = pygame.time.get_ticks()
if current_time - last_spawn > PIPE_SPAWN_INTERVAL:
pipes.append(create_pipe())
last_spawn = current_time
if not game_over:
# Update bird
bird.update()
# Move pipes
for pipe in pipes:
pipe['top'].x -= PIPE_SPEED
pipe['bottom'].x -= PIPE_SPEED
# Remove off-screen pipes
pipes = [pipe for pipe in pipes if pipe['top'].x > -PIPE_WIDTH]
# Check collisions with pipes
for pipe in pipes:
if bird.rect.colliderect(pipe['top']) or bird.rect.colliderect(pipe['bottom']):
game_over = True
# Check ground/ceiling collision
if bird.rect.bottom >= SCREEN_HEIGHT or bird.rect.top <= 0:
game_over = True
# Update score
for pipe in pipes:
if pipe['top'].x + PIPE_WIDTH < bird.rect.left and not pipe['passed']:
score += 1
pipe['passed'] = True
# Draw everything
screen.fill((0, 0, 0)) # Black background
# Draw bird
pygame.draw.rect(screen, (255,4, 0), bird.rect)
# Draw pipes
for pipe in pipes:
pygame.draw.rect(screen, (0, 255, 0), pipe['top'])
pygame.draw.rect(screen, (0, 255, 0), pipe['bottom'])
# Draw score
score_text = font.render(f"Score: {score}", True, (255, 255, 255))
screen.blit(score_text, (10, 10))
if game_over:
game_over_text = font.render("Game Over!", True, (255, 255, 255))
screen.blit(game_over_text, (SCREEN_WIDTH//2 - 100, SCREEN_HEIGHT//2 - 20))
pygame.display.update()
clock.tick(60)
pygame.quit()
```
### Explanation
1. **Bird Class**: The bird's position and velocity are managed. The bird jumps when the space key is pressed.
2. **Pipe Generation**: Pipes spawn at intervals with random gaps. Each pipe pair consists of a top and bottom pipe.
3. **Movement**: Pipes move leftwards each frame. The bird's position is updated with gravity.
4. **Collision Detection**: The game checks for collisions between the bird and pipes, ground, or ceiling.
5. **Score Tracking**: The score increases each time the bird passes a pipe pair.
6. **Game Over**: When collisions occur, the game ends and displays "Game Over".
This code provides a functional Flappy Bird game where the player controls the bird to navigate through pipes while tracking the score. [end of text]
llama_perf_sampler_print: sampling time = 1502.63 ms / 7822 runs ( 0.19 ms per token, 5205.55 tokens per second)
llama_perf_context_print: load time = 159520.51 ms
llama_perf_context_print: prompt eval time = 16079.96 ms / 12 tokens ( 1340.00 ms per token, 0.75 tokens per second)
llama_perf_context_print: eval time = 22287972.94 ms / 7809 runs ( 2854.14 ms per token, 0.35 tokens per second)
llama_perf_context_print: total time = 22314721.41 ms / 7821 tokens
推論にかかった時間は22,288秒 = 約6時間12分。
(4) 速度
待ちきれずCTRL+Cしたとき
llama-cliコマンドを叩いて何分か推論させた後、すぐにCTRL+Cしたときに表示されたときに表示された計測結果がこちら。
llama_perf_sampler_print: sampling time = 14.60 ms / 136 runs ( 0.11 ms per token, 9317.62 tokens per second)
llama_perf_context_print: load time = 147584.12 ms
llama_perf_context_print: prompt eval time = 16745.59 ms / 12 tokens ( 1395.47 ms per token, 0.72 tokens per second)
llama_perf_context_print: eval time = 191373.11 ms / 123 runs ( 1555.88 ms per token, 0.64 tokens per second)
llama_perf_context_print: total time = 209382.00 ms / 135 tokens
Interrupted by user
0.64トークン/秒。
最後まで我慢したとき
数時間かけて我慢したときの結果がこちら。
llama_perf_sampler_print: sampling time = 1502.63 ms / 7822 runs ( 0.19 ms per token, 5205.55 tokens per second)
llama_perf_context_print: load time = 159520.51 ms
llama_perf_context_print: prompt eval time = 16079.96 ms / 12 tokens ( 1340.00 ms per token, 0.75 tokens per second)
llama_perf_context_print: eval time = 22287972.94 ms / 7809 runs ( 2854.14 ms per token, 0.35 tokens per second)
llama_perf_context_print: total time = 22314721.41 ms / 7821 tokens
0.35トークン/秒。
いずれも、SSDのDisk I/Oが激しくGPUのUsageはほぼ0%。メインメモリ+VRAMが80GB以上あるとスムースらしいのですが・・・。
3. まとめ
(1) メインメモリ: 32GB、RTX 4090(24GB) x1枚
--n-gpu-layers 8のとき、0.35 ~ 0.64 トークン/秒
以下は、アレコレいろいろなマシンで試した参考値です。
(2) メインメモリ: 49GB、RTX 4090(24GB) + RTX 4090 Laptop GPU(16GB)
--n-gpu-layers 12のとき、0.89トークン/秒
(3) メインメモリ: 256GB、A100(80GB) x 2枚
--n-gpu-layers 62のとき、OOM
--n-gpu-layers 61のとき、8.77 トークン/秒
--n-gpu-layers 指定無しのとき、3.03 トークン/秒
メインメモリも潤沢なほうがよい(=速い)ですね。