Question : Real-world use cases for Step-3.5-Flash
Hi everyone đ
Curious how people are actually using Step-3.5-Flash in real applications.
If youâre running it in production or experimenting seriously, weâd love to hear:
Post your comment below
Hello @Geodd I was curious about this model but I was in no hurry to test it for myself, since I've never heard of stepfun-ai. Also, I have a lot of projects in development so my GPU rig stays rather busy doing actual work, usually with Minimax 2.1 as my daily driver. I did however give this model a try and I must say I'm rather impressed. Scratch that, I'm a bit blown away be the ability of this model to get to work and code. I honestly didn't think anything would ever give me reason to spin down Minimax 2.1 but this model did. I've been putting it through its paces HEAVILY. It is coding non-stop for me. After a few quick hitter projects, I decided to let it loose on a bigger project. It took all the documentation, asked a bunch of clarifying questions, created an 8 phase plan with about 10-12 tasks per phase and now it's ripping through phases and tasks. Did I mention how stupid fast this model is? I may never fire up Minimax M2.1 again. GLM 4.7 will be deleted to get some space back.
Hello @Geodd I was curious about this model but I was in no hurry to test it for myself, since I've never heard of stepfun-ai. Also, I have a lot of projects in development so my GPU rig stays rather busy doing actual work, usually with Minimax 2.1 as my daily driver. I did however give this model a try and I must say I'm rather impressed. Scratch that, I'm a bit blown away be the ability of this model to get to work and code. I honestly didn't think anything would ever give me reason to spin down Minimax 2.1 but this model did. I've been putting it through its paces HEAVILY. It is coding non-stop for me. After a few quick hitter projects, I decided to let it loose on a bigger project. It took all the documentation, asked a bunch of clarifying questions, created an 8 phase plan with about 10-12 tasks per phase and now it's ripping through phases and tasks. Did I mention how stupid fast this model is? I may never fire up Minimax M2.1 again. GLM 4.7 will be deleted to get some space back.
Wow the team who built the model will be very happy to see this comment! Running a 200b model locally is challenging, what does your rig setup look like and any quantisation ?
I've run the Int8 and Int4 GGUF. The safetensors probably won't fit comfortably on my rig, which has 3x RTX PRO 6000 Blackwell. This model is too big to fit in two cards and vllm won't split across 3 GPU. when i get the 4th gpu, i'll be able to run this and some others, using vllm or sglang and I can ditch llama.cpp for good.
Very good model, it uses very little amount of just 210Gb RAM in Q8 quality(context size 131072 the max possible in obabooga, in cli possible more=more ram). The little example of its work below:
#My Hardware# Intel Xeon E5-2699v4 LGA2011-3 22 cores 44 threads (2016) $110 # Gigabyte C612 chipset 12 RAM slots VGA motherboard year 2016 $150 # Samsung-Hynix ECC RAM 12x64Gb=768Gb ~$900 # VGA monitor # IKEA chair # Run: Trillions Deepseeks, Kimis in Q5-Q6, 400-500billions in BF16
Prompt: Lets invent something to draw in real life!
Ai (result after thinking which is too long):
Open-Source XY Plotter: Complete Documentation & Software Pipeline
1. Project Overview
This project details the construction of a homemade XY plotter â a computer-controlled drawing machine that reproduces images on paper using a motorized pen. The system consists of:
- Mechanical hardware: An XâY gantry driven by stepper motors, with a penâlift mechanism.
- Electronics: An Arduinoâbased controller running GRBL firmware.
- Software: A Python imageâtoâGâcode pipeline that converts raster/vector images into drawing commands.
(Note: In actual documentation, insert a visual block diagram showing: Image â Python script â Gâcode â Serial â Arduino GRBL â Motors/Pen)
2. Mechanical Design
2.1. Bill of Materials (BOM)
| Part | Specification | Qty | Notes |
|---|---|---|---|
| Frame | 20âŻĂâŻ20âŻmm aluminum extrusion (or PVC/wood) | ~4âŻm | Cut to size: two lengths for Yârails (e.g., 600âŻmm), two for ends |
| Xâaxis beam | 20âŻĂâŻ20âŻmm extrusion or carbon fiber rod | 1 | Length = Yâtravel (e.g., 400âŻmm) |
| Stepper motors | NEMAâŻ17, 1.8°/step, 1.5âŻA | 2 | High torque recommended |
| Motor drivers | A4988 or DRV8825 | 2 | Microstepping up to 1/16 |
| Belts & pulleys | GT2 timing belt, 2âŻmm pitch; GT2 pulley 20âŻT | ~2âŻm + 2 | Belt length depends on frame size |
| Linear bearings | LM8UU (for 8âŻmm shaft) or SC8UU (for 8âŻmm rail) | 4â6 | For Yârails and Xâcarriage |
| Shafts/Rails | 8âŻmm smooth rod or linear rail | 2âŻĂâŻYâtravel | For Yâaxis motion |
| Pen mechanism | Micro servo (MG90S) or solenoid (5âŻV) | 1 | Servo for pressure control, solenoid simpler |
| Pen holder | 3Dâprinted or custom bracket | 1 | Holds pen vertically, adjustable height |
| Power supply | 12âŻV DC, 5âŻA (or 24âŻV for faster motors) | 1 | Switchâmode, with appropriate connector |
| Arduino board | Arduino Uno or Nano | 1 | |
| CNC shield | Arduino Uno CNC shield V3 | 1 | For easy driver/endstop wiring |
| Endstops | Mechanical micro switches (NO) | 2 (optional) | For homing; optional if no homing |
| Misc | M3/M4 screws, nuts, brackets, wires | â | As needed |
2.2. Mechanical Layout
Top view (Yâaxis beam moves frontâback, Xâcarriage moves leftâright):
Y (front)
^
|
| +-----------------+ <-- Yâaxis beam (moves on Yârails)
| | Xâcarriage |
| | (pen up/down) |
| +--------+--------+
| |
| | X (right)
+------------+-----> X
|
| Paper (origin at bottomâleft)
Side view (pen vertical movement):
Z (pen up/down)
^
|
| Servo/Solenoid
| +-----+
| | Pen |
| +-----+
| |
+-----+--- Xâcarriage
|
| Xâbeam (horizontal)
|
| Yârails (vertical)
|
+--- Paper
Key design points:
- Yâaxis: The beam spans the desired drawing width. Two parallel rails (smooth rods or linear rails) guide the beamâs motion via bearings. A stepper motor drives the belt attached to the beam.
- Xâaxis: A carriage slides on the beam (using bearings or a second belt). Another stepper moves the carriage leftâright.
- Pen axis: The pen is mounted on the carriage with its tip just touching the paper. A servo rotates an arm to lift/drop the pen; a solenoid pushes/pulls directly. Adjustable height for different pens.
- Frame rigidity: Use crossâbracing to prevent wobble. All moving parts should have minimal backlash.
2.3. Assembly Steps
- Build the base frame (rectangular) with extrusions.
- Mount Yârails vertically (parallel, same plane). Ensure they are level and square.
- Install Yâaxis bearings on the beam and attach beam to Yârails.
- Attach Yâmotor and belt to beam (pulley on motor, idler on opposite end).
- Build Xâcarriage: mount bearings on beam, attach belt.
- Mount Xâmotor on one end of the beam.
- Install pen mechanism on carriage. Adjust so pen tip just touches paper when âdownâ.
- Wire electronics (see sectionâŻ3).
- Test motion manually (with power off) to ensure smooth travel.
3. Electronics & Firmware
3.1. Wiring Diagram
Arduino + CNC Shield
|--- Stepper X (Xâaxis) -> A4988 X (X1,X2)
|--- Stepper Y (Yâaxis) -> A4988 Y (Y1,Y2)
|--- Servo/Solenoid -> Spindle enable (or free PWM pin)
|--- Power (12âŻV) to VâMot
|--- Arduino USB â Computer
- Stepper connections: A4988
STEPandDIRto CNC shield pins,ENABLEto ground (always enabled) or useENABLEpin. - Servo: Connect signal to any PWM pin (e.g., D9 on Uno). Power from Arduino 5âŻV if small servo (MG90S); for larger, use separate 5âŻV.
- Solenoid: Connect via transistor (e.g., TIP120) to a digital pin; include flyback diode.
- GRBLâs spindle control: If using digital spindle, set
spindle_type=1in GRBL config. The spindle enable pin (usually D11 on Uno) will be toggled by M3/M5.
3.2. GRBL Firmware
Install Arduino IDE, add GRBL library or upload
grblsketch (from https://github.com/gnea/grbl).Configure GRBL (using Universal G-code Sender or
grbl Console):$0=80(step pulse, microseconds, usually 10â20)$1=25(step idle delay, ms)$2=0(step port invert mask)$3=0(dir port invert mask)$4=0(step enable invert)$5=0(limit pins invert)$6=0(probe pin invert)$10=1(status report mask)$11=0.010(junction deviation, mm)$12=0.002(arc tolerance, mm)$13=0(report inches)$20=0(soft limits enable)$21=0(hard limits enable)$22=1(homing cycle enable) â 0 if no homing$23=0(homing dir invert mask)$24=25.0(homing locate feed rate, mm/min)$25=500.0(homing search feed rate, mm/min)$26=250(homing switch debounce, ms)$27=1.0(homing switch pullâoff distance, mm)$100=80.0(X steps/mm) â calculate from your hardware$101=80.0(Y steps/mm)$110=500.0(X max rate, mm/min)$111=500.0(Y max rate)$120=300.0(X acceleration, mm/sec²)$121=300.0(Y acceleration)$130=200.0(X max travel, mm) â set to your drawing area$131=200.0(Y max travel)
Steps per mm calculation:
- For GT2 belt with 20âtooth pulley:
steps_per_mm = (200 steps/rev * microsteps) / (2 mm/pitch * 20 teeth)
Example: 1/16 microstep â(200*16)/(2*20) = 80 steps/mm. - For lead screw:
(steps * microsteps) / screw_pitch.
- For GT2 belt with 20âtooth pulley:
Spindle (pen) setup: In GRBL,
spindle_type=1for digital (on/off). The spindle output pin will be HIGH when pen down (M3), LOW when up (M5). You may need to invert depending on wiring: setspindle_invert=1in config.Test motion using Universal Gâcode Sender (UGS) or
grbl Console. SendG1 X10 Y10 F500to check both axes move correctly.
4. Software Pipeline
4.1. HighâLevel Workflow
Input image (PNG/JPG)
|
v
[Image preprocessing] (grayscale, threshold, edge/contour)
|
v
[Vector extraction] (contour tracing, polyline simplification)
|
v
[Scaling] (map to machine coordinate space, flip Y)
|
v
[Gâcode generation] (insert M3/M5, convert to G0/G1)
|
v
Serial transmission (send to GRBL lineâbyâline with flow control)
|
v
Physical drawing
4.2. Image Processing Options
- Contour mode (default): Convert image to binary (threshold), extract external contours. Good for line art, silhouettes.
- Edge mode: Use Canny edge detection, then find contours from edges.
- Dither mode (advanced): Ordered dithering â stippling (draw dots). Not covered in base code but can be added.
Weâll implement contour mode using OpenCV.
5. Python Implementation
5.1. Dependencies
pip install opencv-python numpy pyserial
5.2. Main Script: plotter.py
#!/usr/bin/env python3
"""
XY Plotter: Convert image to G-code and send to GRBL.
"""
import cv2
import numpy as np
import serial
import time
import argparse
import sys
def load_and_preprocess(image_path, threshold=128):
"""Load image, grayscale, binary threshold, invert if needed."""
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if img is None:
raise FileNotFoundError(f"Cannot load {image_path}")
# Binarize: dark pixels become foreground (1), light background (0)
_, binary = cv2.threshold(img, threshold, 255, cv2.THRESH_BINARY_INV)
return binary
def extract_contours(binary, epsilon_factor=0.01):
"""Find and approximate contours to polylines."""
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
polylines = []
for cnt in contours:
if len(cnt) < 2:
continue
# Approximate to reduce points (epsilon as fraction of arc length)
arc_len = cv2.arcLength(cnt, closed=True)
epsilon = epsilon_factor * arc_len
approx = cv2.approxPolyDP(cnt, epsilon, closed=True)
# Convert to list of (x, y) tuples
polyline = [tuple(pt[0]) for pt in approx]
polylines.append(polyline)
return polylines
def scale_to_machine(polylines, machine_width, machine_height, img_width, img_height):
"""Scale image coordinates to machine mm coordinates. Flips Y to have origin bottom-left."""
scale_x = machine_width / img_width
scale_y = machine_height / img_height
scaled_polylines = []
for poly in polylines:
new_poly = []
for (x, y) in poly:
mx = x * scale_x
my = y * scale_y
# Flip Y: machine Y increases upward; image Y increases downward
my = machine_height - my
new_poly.append((mx, my))
scaled_polylines.append(new_poly)
return scaled_polylines
def generate_gcode(polylines, feed_rate=1000, pen_up_delay=0.1, pen_down_delay=0.1):
"""Generate G-code string with pen control via M3 (digital on) and M5 (off)."""
gcode_lines = []
gcode_lines.append("G21 ; mm units")
gcode_lines.append("G90 ; absolute positioning")
gcode_lines.append("G94 ; feed rate per minute")
for i, poly in enumerate(polylines):
if len(poly) < 2:
continue
# Pen up before moving to start
gcode_lines.append("M5 ; pen up")
# Rapid move to first point
x0, y0 = poly[0]
gcode_lines.append(f"G0 X{x0:.3f} Y{y0:.3f} F{feed_rate}")
# Pen down
gcode_lines.append("M3 S1 ; pen down")
# Draw the polyline
for (x, y) in poly[1:]:
gcode_lines.append(f"G1 X{x:.3f} Y{y:.3f} F{feed_rate}")
# Lift pen after contour
gcode_lines.append("M5 ; pen up")
# Optional short pause
if pen_up_delay > 0:
gcode_lines.append(f"G4 P{pen_up_delay:.3f}")
# End program
gcode_lines.append("M5 ; ensure pen up")
gcode_lines.append("M2 ; program end")
return "\n".join(gcode_lines)
def send_gcode(ser, gcode_str, wait_for_ok=True):
"""Send G-code line by line, waiting for 'ok' if required."""
lines = gcode_str.strip().split('\n')
for line in lines:
# Strip comments and empty lines
clean = line.split(';')[0].strip()
if not clean:
continue
# GRBL expects line ending with \n
ser.write((clean + '\n').encode())
if wait_for_ok:
# Wait for 'ok' or 'error'
while True:
resp = ser.readline().decode().strip()
if resp == 'ok':
break
elif resp.startswith('error'):
print(f"GRBL error: {resp}")
break
# else ignore other status reports
# Small delay to buffer
time.sleep(0.01)
def main():
parser = argparse.ArgumentParser(description="XY Plotter Image to G-code")
parser.add_argument('image', help='Input image file')
parser.add_argument('--width', type=float, required=True, help='Machine X travel (mm)')
parser.add_argument('--height', type=float, required=True, help='Machine Y travel (mm)')
parser.add_argument('--port', default='COM3', help='Serial port (e.g., COM3 or /dev/ttyUSB0)')
parser.add_argument('--baud', type=int, default=115200, help='Baud rate')
parser.add_argument('--threshold', type=int, default=128, help='Binarization threshold 0-255')
parser.add_argument('--epsilon', type=float, default=0.01, help='Contour simplification factor (0-0.1)')
parser.add_argument('--feed', type=int, default=1000, help='Feed rate (mm/min)')
args = parser.parse_args()
# 1. Preprocess
binary = load_and_preprocess(args.image, args.threshold)
h, w = binary.shape
# 2. Extract contours
polylines = extract_contours(binary, args.epsilon)
print(f"Found {len(polylines)} contours")
# 3. Scale to machine
machine_polylines = scale_to_machine(polylines, args.width, args.height, w, h)
# 4. Generate G-code
gcode = generate_gcode(machine_polylines, feed_rate=args.feed)
# Optionally save G-code file for inspection
with open('output.gcode', 'w') as f:
f.write(gcode)
print("G-code saved to output.gcode (length: {} lines)".format(len(gcode.splitlines())))
# 5. Send to GRBL
try:
ser = serial.Serial(args.port, args.baud, timeout=1)
time.sleep(2) # Wait for Arduino reset
# Initialize GRBL: clear buffer
ser.write(b'\r\n\r\n')
time.sleep(0.5)
ser.flushInput()
print(f"Connected to {args.port} at {args.baud} baud")
# Optional: query status to ensure alive
ser.write(b'?')
time.sleep(0.1)
print("Status:", ser.readline().decode().strip())
# Send G-code
print("Sending G-code...")
send_gcode(ser, gcode, wait_for_ok=True)
print("Done.")
except serial.SerialException as e:
print(f"Serial error: {e}")
sys.exit(1)
finally:
if 'ser' in locals() and ser.is_open:
ser.close()
if __name__ == '__main__':
main()
5.3. Usage Examples
# Basic usage: draw a black-and-white logo
python plotter.py logo.png --width 200 --height 200 --port COM3
# With higher simplification (fewer points) and slower feed
python plotter.py photo.jpg --width 300 --height 200 --epsilon 0.02 --feed 600
Tips:
- Adjust
--thresholdto get desired features. Use0for original inverted binary? Actually we invert because we want dark pixels as drawing. If your image has light lines on dark background, change thresholding. - Use
--epsilonto reduce point count; too high loses detail. - Set
--feedbased on motor capabilities; startä˝é (200â500 mm/min) for testing.
6. Calibration & Testing
- Mechanical limits: Ensure the plotter does not hit frame edges. Manually jog axes using UGS to find safe travel area.
- Steps/mm verification: Move a known distance (e.g., 100âŻmm) and measure actual travel. Adjust
$100/$101in GRBL accordingly. - Pen height: The pen should lightly touch paper when down; adjust mounting so it doesnât drag or skip.
- Test pattern: Draw a simple square or circle. Check for:
- Backlash: Corners may be rounded. Improve belt tension/antiâbacklash mechanisms.
- Scaling: If drawing is too small/large, adjust machine dimensions in
scale_to_machine. - Skew: If axes not perpendicular, square the frame.
- Gâcode flow: If motors stutter, reduce feed rate or acceleration in GRBL (
$120,$121).
7. Advanced Enhancements
- Hatching/Fill: For solid areas, generate parallel line fills (requires contour interior detection).
- Multiâcolor: Multiple pen holders with automatic tool change (complex).
- Web interface: Use Flask/Django to upload images and control remotely.
- Optimization: Solve TSP for contour order to minimize travel; use
networkxorortools. - Variable line width: Control pen pressure via servo angle (map to grayscale intensity).
8. Troubleshooting Table
| Symptom | Possible Cause | Fix |
|---|---|---|
| Motors donât move | Wiring incorrect, GRBL not configured, power off | Check connections, verify GRBL $ settings, ensure 12âŻV to drivers |
| Stuttering/skipping | Feed rate too high, acceleration too high | Lower $110/$111 (max rate) and $120/$121 (acceleration) |
| Drawings are upsideâdown | Yâaxis inverted | In software, flip Y; or set $3=4 (Y dir invert) in GRBL |
| Pen marks too light/heavy | Pen height wrong, servo not full travel | Adjust pen mounting; calibrate servo angle range in GRBL spindle settings |
| Gâcode not executing, error alarms | Gâcode syntax error, serial buffer overflow | Ensure Gâcode lines terminated with \n; add waits for ok; check GRBL config |
| Contours look pixelated/low detail | epsilon too large |
Decrease --epsilon value; use smaller microstepping? No, just more points |
| Machine moves beyond paper | Soft limits disabled or set incorrectly | Set $130/$131 to machine travel, enable soft limits ($20=1) or use endstops |
9. Safety & Best Practices
- Power: Use a fused power supply. Never connect/disconnect steppers while powered.
- Pen: Use a suitable pen (technical pen, ballâpoint) that doesnât leak. Secure it tightly.
- Supervision: Never leave the plotter unattended while running; motors can overheat or jam.
- Noise: Steppers can be noisy; consider stepper dampers or a enclosure.
10. Conclusion
You now have complete documentation to build a functional XY plotter: a mechanical design with readily available parts, electronics with GRBL firmware, and a Python pipeline that transforms images into Gâcode. Start with a simple frame (maybe cardboard or wood) to validate the system, then refine mechanics for precision. Experiment with different image processing parameters to achieve artistic effects. Letâs create art! đ¨
Remember: iterate, calibrate, and share your improvements with the openâsource community.
This is the first model I've actually successfully used on my production Java codebase (few thousand classes). Running IQ4_XS quants on 120k context (Q8 KV cache).
Absolutely in love with the model, perfectly coherent, great at understanding the codebase, haven't had one faulty tool call in probably a few hundred calls. Resolved a real-life issue with minimal support (I knew what the issue was, so I decided it would be a great test for the model and surprisingly it aced it mostly without my help).
I'm actually kinda shocked the AI channels and discussions online haven't been talking more about this model. The fact I'm running this instead of Minimax 2.1 or GLM 4.7 should say a LOT about it's capability. This is a blazing fast, super competent model that knows how to code. This is the kind of model local LLM people should be talking about non-stop. It's that good.
I agree, this is a bit less in the spotlight. I was comparing with MiniMax M2.1 and found this is more accurate in complex programming challenges and is smaller. Though I use the Q6 quantized model. I have only one issue integrating into programming tools like Claude Code/Kilo Code as for tool calls it always returns 500 (running with llama-server), probably have to check the jinja template. But nevertheless great work guys, big RESPECT!